cc-os/plugins/cc-architect/scripts/plugin_config/test/test_operations.rb

369 lines
11 KiB
Ruby

# frozen_string_literal: true
require_relative 'test_helper'
# ─── Enable ───────────────────────────────────────────────────────────────────
class TestEnable < Minitest::Test
include TestHelpers
def setup
setup_temp_dirs
end
def teardown
teardown_temp_dirs
end
def test_enable_new_plugin_creates_file_and_adds_entry
op = make_operation(PluginConfig::Operations::Enable)
result = op.call
assert_includes %w[created_and_enabled enabled], result[:status]
assert_equal 'test-plugin@test-marketplace', result[:plugin]
assert result[:verified], 'Expected verified to be true'
assert_includes result[:enabled_plugins], 'test-plugin@test-marketplace'
end
def test_enable_adds_to_existing_settings
create_settings('other-plugin@other-marketplace' => true)
op = make_operation(PluginConfig::Operations::Enable)
result = op.call
assert_equal 'enabled', result[:status]
assert_includes result[:enabled_plugins], 'other-plugin@other-marketplace'
assert_includes result[:enabled_plugins], 'test-plugin@test-marketplace'
end
def test_enable_already_enabled_returns_already_enabled
create_settings('test-plugin@test-marketplace' => true)
op = make_operation(PluginConfig::Operations::Enable)
result = op.call
assert_equal 'already_enabled', result[:status]
assert result[:verified]
end
def test_enabled_plugins_sorted_alphabetically
create_settings('z-plugin@z-marketplace' => true, 'a-plugin@a-marketplace' => true)
op = make_operation(PluginConfig::Operations::Enable)
result = op.call
expected = ['a-plugin@a-marketplace', 'test-plugin@test-marketplace', 'z-plugin@z-marketplace']
assert_equal expected, result[:enabled_plugins]
end
def test_verified_flag_is_true_on_success
op = make_operation(PluginConfig::Operations::Enable)
result = op.call
assert result[:verified]
end
end
# ─── Disable ──────────────────────────────────────────────────────────────────
class TestDisable < Minitest::Test
include TestHelpers
def setup
setup_temp_dirs
end
def teardown
teardown_temp_dirs
end
def test_disable_existing_plugin_removes_entry
create_settings('test-plugin@test-marketplace' => true)
op = make_operation(PluginConfig::Operations::Disable)
result = op.call
assert_equal 'disabled', result[:status]
refute_includes result[:remaining_plugins], 'test-plugin@test-marketplace'
end
def test_disable_nonexistent_plugin_returns_not_found
create_settings({})
op = make_operation(PluginConfig::Operations::Disable)
result = op.call
assert_equal 'not_found', result[:status]
end
def test_disable_preserves_other_plugins
create_settings(
'test-plugin@test-marketplace' => true,
'keep-me@other' => true
)
op = make_operation(PluginConfig::Operations::Disable)
result = op.call
assert_equal 'disabled', result[:status]
assert_includes result[:remaining_plugins], 'keep-me@other'
refute_includes result[:remaining_plugins], 'test-plugin@test-marketplace'
end
def test_verified_flag_confirms_key_absent
create_settings('test-plugin@test-marketplace' => true)
op = make_operation(PluginConfig::Operations::Disable)
result = op.call
assert result[:verified]
end
end
# ─── Register ─────────────────────────────────────────────────────────────────
class TestRegister < Minitest::Test
include TestHelpers
def setup
setup_temp_dirs
end
def teardown
teardown_temp_dirs
end
def test_register_new_plugin_adds_to_marketplace
create_marketplace(plugins: [])
op = make_operation(PluginConfig::Operations::Register, description: 'A test plugin')
result = op.call
assert_equal 'registered', result[:status]
assert result[:verified]
data = JSON.parse(File.read(marketplace_path))
names = data['plugins'].map { |p| p['name'] }
assert_includes names, 'test-plugin'
end
def test_register_already_present_returns_already_registered
create_marketplace(plugins: [{ 'name' => 'test-plugin', 'source' => './test-plugin', 'description' => '' }])
op = make_operation(PluginConfig::Operations::Register)
result = op.call
assert_equal 'already_registered', result[:status]
assert result[:verified]
end
def test_plugins_array_sorted_by_name
create_marketplace(plugins: [{ 'name' => 'z-plugin', 'source' => './z-plugin', 'description' => '' }])
op = make_operation(PluginConfig::Operations::Register, plugin: 'a-plugin')
result = op.call
data = JSON.parse(File.read(marketplace_path))
names = data['plugins'].map { |p| p['name'] }
assert_equal %w[a-plugin z-plugin], names
end
def test_description_is_stored_correctly
create_marketplace(plugins: [])
op = make_operation(PluginConfig::Operations::Register, description: 'My description')
result = op.call
data = JSON.parse(File.read(marketplace_path))
plugin_entry = data['plugins'].find { |p| p['name'] == 'test-plugin' }
assert_equal 'My description', plugin_entry['description']
end
end
# ─── Unregister ───────────────────────────────────────────────────────────────
class TestUnregister < Minitest::Test
include TestHelpers
def setup
setup_temp_dirs
end
def teardown
teardown_temp_dirs
end
def test_unregister_existing_plugin
create_marketplace(plugins: [{ 'name' => 'test-plugin', 'source' => './test-plugin', 'description' => '' }])
op = make_operation(PluginConfig::Operations::Unregister)
result = op.call
assert_equal 'unregistered', result[:status]
assert result[:verified]
data = JSON.parse(File.read(marketplace_path))
names = data['plugins'].map { |p| p['name'] }
refute_includes names, 'test-plugin'
end
def test_unregister_nonexistent_returns_not_found
create_marketplace(plugins: [])
op = make_operation(PluginConfig::Operations::Unregister)
result = op.call
assert_equal 'not_found', result[:status]
end
def test_unregister_preserves_other_plugins
create_marketplace(plugins: [
{ 'name' => 'keep-me', 'source' => './keep-me', 'description' => '' },
{ 'name' => 'test-plugin', 'source' => './test-plugin', 'description' => '' }
])
op = make_operation(PluginConfig::Operations::Unregister)
result = op.call
data = JSON.parse(File.read(marketplace_path))
names = data['plugins'].map { |p| p['name'] }
assert_includes names, 'keep-me'
refute_includes names, 'test-plugin'
end
end
# ─── Audit ────────────────────────────────────────────────────────────────────
class TestAudit < Minitest::Test
include TestHelpers
def setup
setup_temp_dirs
# Create installed_plugins in temp location; override the path
@installed_path = File.join(@tmpdir, 'installed_plugins.json')
end
def teardown
teardown_temp_dirs
end
def test_clean_state_returns_ok
# Create all required files with correct entries
create_marketplace(plugins: [{ 'name' => 'test-plugin', 'source' => './test-plugin', 'description' => '' }])
create_settings('test-plugin@test-marketplace' => true)
# Need to stub installed_plugins_path - create a subclass
op = make_audit_op_with_installed({ 'test-plugin@test-marketplace' => { 'status' => 'enabled' } })
result = op.call
assert_equal 'ok', result[:status]
assert_empty result[:issues]
end
def test_missing_marketplace_entry_reports_issue_with_fix
create_marketplace(plugins: []) # plugin not registered
create_settings('test-plugin@test-marketplace' => true)
op = make_audit_op_with_installed({ 'test-plugin@test-marketplace' => { 'status' => 'enabled' } })
result = op.call
assert_equal 'issues_found', result[:status]
marketplace_check = result[:checks][:marketplace]
assert_equal 'issue', marketplace_check[:status]
assert marketplace_check[:fix]
end
def test_missing_settings_entry_reports_issue_with_fix
create_marketplace(plugins: [{ 'name' => 'test-plugin', 'source' => './test-plugin', 'description' => '' }])
create_settings({}) # plugin not enabled
op = make_audit_op_with_installed({ 'test-plugin@test-marketplace' => { 'status' => 'enabled' } })
result = op.call
assert_equal 'issues_found', result[:status]
settings_check = result[:checks][:settings]
assert_equal 'issue', settings_check[:status]
assert settings_check[:fix]
end
def test_multiple_issues_all_reported
create_marketplace(plugins: []) # not registered
create_settings({}) # not enabled
op = make_audit_op_with_installed({}) # not installed
result = op.call
assert_equal 'issues_found', result[:status]
assert result[:issues].length >= 2, "Expected at least 2 issues, got #{result[:issues].length}"
end
private
# Create an Audit subclass that overrides installed_plugins_path to use temp dir
def make_audit_op_with_installed(installed_plugins)
installed_path = @installed_path
create_installed_plugins(installed_path, installed_plugins)
params = {
plugin: 'test-plugin',
marketplace: 'test-marketplace',
project: @project_dir,
marketplace_file: marketplace_path
}
op = PluginConfig::Operations::Audit.new(params)
# Override the installed_plugins_path method
op.define_singleton_method(:installed_plugins_path) { installed_path }
op
end
end
# ─── List ─────────────────────────────────────────────────────────────────────
class TestList < Minitest::Test
include TestHelpers
def setup
setup_temp_dirs
end
def teardown
teardown_temp_dirs
end
def test_list_returns_all_enabled_plugins
create_settings(
'b-plugin@marketplace' => true,
'a-plugin@marketplace' => true
)
op = make_operation(PluginConfig::Operations::List)
result = op.call
assert_equal 'ok', result[:status]
assert_equal %w[a-plugin@marketplace b-plugin@marketplace], result[:enabled_plugins]
assert_equal 2, result[:count]
end
def test_list_empty_settings_returns_empty_array
create_settings({})
op = make_operation(PluginConfig::Operations::List)
result = op.call
assert_equal 'ok', result[:status]
assert_empty result[:enabled_plugins]
assert_equal 0, result[:count]
end
def test_list_missing_file_returns_empty_array
# Don't create settings file
op = make_operation(PluginConfig::Operations::List)
result = op.call
assert_equal 'ok', result[:status]
assert_empty result[:enabled_plugins]
assert_equal 0, result[:count]
end
end