diff --git a/tests/test_plugin_preferences_regressions.py b/tests/test_plugin_preferences_regressions.py new file mode 100644 index 0000000..3b67415 --- /dev/null +++ b/tests/test_plugin_preferences_regressions.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 + +"""Regression tests for the plugin controls in Preferences.""" + +import unittest +from unittest import mock + +from cthulhu import cthulhu # Import first to satisfy the application's initialization order. +from cthulhu import cthulhu_gui_prefs + + +class PluginPreferencesRegressionTests(unittest.TestCase): + """Keep plugin state changes independent from their presentation widgets.""" + + @staticmethod + def _create_gui(): + gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__( + cthulhu_gui_prefs.CthulhuSetupGUI + ) + gui.prefsDict = { + "activePlugins": ["HiddenPlugin", "SourceOne"], + "pluginSources": ["https://example.com/plugins.git"], + } + gui._available_plugins = {"HiddenPlugin", "SourceOne", "SourceTwo", "Required"} + gui._plugin_entries = { + "SourceOne": {"active": True, "can_toggle": True}, + "SourceTwo": {"active": False, "can_toggle": True}, + "Required": {"active": True, "can_toggle": False}, + } + gui._plugin_canonical_map = { + "SourceOne": "SharedPlugin", + "SourceTwo": "SharedPlugin", + "Required": "Required", + } + gui._plugin_group_map = { + "SharedPlugin": ["SourceOne", "SourceTwo"], + "Required": ["Required"], + } + gui._update_selected_plugin_controls = mock.Mock() + gui._update_plugin_tabs = mock.Mock() + return gui + + def test_active_plugins_include_hidden_and_selected_plugins(self): + gui = self._create_gui() + + self.assertEqual( + gui._get_active_plugins_from_ui(), + ["HiddenPlugin", "SourceOne", "Required"], + ) + + def test_enabling_plugin_disables_other_copy_with_same_name(self): + gui = self._create_gui() + + gui._set_plugin_active("SourceTwo", True) + + self.assertFalse(gui._plugin_entries["SourceOne"]["active"]) + self.assertTrue(gui._plugin_entries["SourceTwo"]["active"]) + gui._update_selected_plugin_controls.assert_called_once_with() + gui._update_plugin_tabs.assert_called_once_with() + + def test_required_plugin_cannot_be_disabled(self): + gui = self._create_gui() + + gui._set_plugin_active("Required", False) + + self.assertTrue(gui._plugin_entries["Required"]["active"]) + gui._update_plugin_tabs.assert_not_called() + + def test_apply_does_not_modify_plugin_sources(self): + gui = self._create_gui() + gui._populate_plugin_list = mock.Mock() + + gui._apply_plugin_changes() + + self.assertEqual( + gui.prefsDict["pluginSources"], + ["https://example.com/plugins.git"], + ) + + +if __name__ == "__main__": + unittest.main()