From 9e1ebd9c17b81e6748aa1a61d2135657f51be8c9 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Thu, 17 Sep 2026 08:52:40 -0400 Subject: [PATCH] fix(web): remove the General-tab plugin system toggles that did nothing plugin_system.auto_discover, auto_load_enabled and development_mode had General-tab toggles whose help tips promised dormant plugins and verbose logging, but nothing reads them: every enabled plugin is discovered and loaded regardless. Remove the three toggles. The keys stay tolerated in stored configs. The save handler now stores a flag only when a client sends it; treating a missing key as an unchecked box would otherwise rewrite all three to false on every General-tab save, which still posts plugins_directory. Co-Authored-By: Claude Opus 5 --- test/test_plugin_system_legacy_flags.py | 70 +++++++++++++++++++ web_interface/blueprints/api_v3/config.py | 12 ++-- .../templates/v3/partials/general.html | 42 ++--------- 3 files changed, 82 insertions(+), 42 deletions(-) create mode 100644 test/test_plugin_system_legacy_flags.py diff --git a/test/test_plugin_system_legacy_flags.py b/test/test_plugin_system_legacy_flags.py new file mode 100644 index 00000000..46fb1aed --- /dev/null +++ b/test/test_plugin_system_legacy_flags.py @@ -0,0 +1,70 @@ +"""plugin_system.auto_discover / auto_load_enabled / development_mode. + +The General tab offered three toggles for these, with help tips promising +"plugins installed but dormant" and "verbose logging". Nothing in src/, +web_interface/ or scripts/ reads them: every enabled plugin is discovered and +loaded regardless. The toggles are gone; the keys stay tolerated in stored +configs, and saving the General tab must not rewrite them. +""" +import copy +import json +import sys +from pathlib import Path + +import pytest + +PROJECT_ROOT = Path(__file__).parent.parent +sys.path.insert(0, str(PROJECT_ROOT)) + +from test._api_v3_test_helpers import api_v3_client, api_v3_module # noqa: F401,E402 +from test.test_web_settings_ui import REALISTIC_CONFIG, client # noqa: F401,E402 + +LEGACY_FLAGS = ('auto_discover', 'auto_load_enabled', 'development_mode') + + +def test_the_general_tab_no_longer_offers_the_toggles(client): + body = client.get('/v3/partials/general').get_data(as_text=True) + for flag in LEGACY_FLAGS: + assert f'name="{flag}"' not in body, flag + assert f'setting-general-{flag}' not in body, flag + # The setting that does work stays. + assert 'name="plugins_directory"' in body + + +@pytest.fixture +def saved(api_v3_module, monkeypatch): + captured = {} + stored = copy.deepcopy(REALISTIC_CONFIG) + stored['plugin_system'].update( + auto_discover=True, auto_load_enabled=True, development_mode=True) + api_v3_module.api_v3.config_manager.load_config.return_value = stored + + def fake_save(_manager, config, **_kwargs): + captured['config'] = config + return True, '' + + monkeypatch.setattr(api_v3_module, '_save_config_atomic', fake_save) + return captured + + +def test_saving_the_general_form_leaves_stored_flags_alone(api_v3_client, saved): + # What the General form posts now: no checkbox fields for the flags. + resp = api_v3_client.post('/api/v3/config/main', data={ + 'timezone': 'America/Chicago', 'city': 'Dallas', 'state': 'Texas', + 'country': 'US', 'plugins_directory': 'plugin-repos', + }) + assert resp.status_code == 200, resp.get_json() + plugin_system = saved['config']['plugin_system'] + # Missing used to mean "unchecked" and saved all three as false. + assert all(plugin_system[flag] is True for flag in LEGACY_FLAGS), plugin_system + assert plugin_system['plugins_directory'] == 'plugin-repos' + + +def test_an_api_client_can_still_store_a_flag(api_v3_client, saved): + resp = api_v3_client.post('/api/v3/config/main', data=json.dumps({ + 'timezone': 'America/Chicago', 'development_mode': False, + }), content_type='application/json') + assert resp.status_code == 200, resp.get_json() + plugin_system = saved['config']['plugin_system'] + assert plugin_system['development_mode'] is False + assert plugin_system['auto_discover'] is True diff --git a/web_interface/blueprints/api_v3/config.py b/web_interface/blueprints/api_v3/config.py index d1bd34d7..1b51f898 100644 --- a/web_interface/blueprints/api_v3/config.py +++ b/web_interface/blueprints/api_v3/config.py @@ -520,10 +520,14 @@ def save_main_config(): if 'plugin_system' not in current_config: current_config['plugin_system'] = {} - # Handle plugin system checkboxes - always set to handle unchecked state - # HTML checkboxes omit the key when unchecked, so missing key = unchecked = False - for checkbox in ['auto_discover', 'auto_load_enabled', 'development_mode']: - current_config['plugin_system'][checkbox] = _coerce_to_bool(data.get(checkbox)) + # auto_discover / auto_load_enabled / development_mode are read by + # nothing and no longer have General-tab toggles. The form still + # posts plugins_directory, so treating a missing key as an + # unchecked box would rewrite stored values to false on every + # save; only store what a client actually sends. + for legacy_flag in ['auto_discover', 'auto_load_enabled', 'development_mode']: + if legacy_flag in data: + current_config['plugin_system'][legacy_flag] = _coerce_to_bool(data.get(legacy_flag)) # Handle plugins_directory if 'plugins_directory' in data: diff --git a/web_interface/templates/v3/partials/general.html b/web_interface/templates/v3/partials/general.html index 9627269a..d088b40d 100644 --- a/web_interface/templates/v3/partials/general.html +++ b/web_interface/templates/v3/partials/general.html @@ -166,44 +166,10 @@

Configure the core plugin system behavior.

- -
- -
- - -
- -
- - -
- -
+