"""Phase 168 (task 02): the settings catalogue is complete and consistent. The Settings panel (task 05) is GENERATED from ``app/core/settings_catalog.py`` — never hand-written — so these pins are load-bearing: ``set(CATALOG) == set(Settings.model_fields)`` fails the build the moment a new ``Settings`` field lands without its metadata (it can never silently disappear from the panel), the group table is closed both directions, and the capability sets are exactly the LOCKED decisions (A3/A4). """ from __future__ import annotations from app.config import Settings from app.core.settings_catalog import ( CATALOG, GROUPS, NON_OVERRIDABLE, RESTART_REQUIRED, SECRETS, SettingMeta, env_var, ) def test_catalog_covers_exactly_model_fields() -> None: """The completeness pin (both directions, the diff in the message).""" catalog_keys = set(CATALOG) field_names = set(Settings.model_fields) missing = sorted(field_names - catalog_keys) extra = sorted(catalog_keys - field_names) assert not missing, ( f"Settings fields missing from the catalogue (invisible in the " f"panel): {missing}" ) assert not extra, ( f"Catalogue entries with no Settings field (stale): {extra}" ) assert set(CATALOG) == set(Settings.model_fields) def test_groups_closed_both_directions() -> None: catalog_groups = {meta.group for meta in CATALOG.values()} only_in_groups = sorted(set(GROUPS) - catalog_groups) only_in_catalog = sorted(catalog_groups - set(GROUPS)) assert not only_in_groups, f"GROUPS entries with no catalogue member: {only_in_groups}" assert not only_in_catalog, f"Catalogue groups missing from GROUPS: {only_in_catalog}" def test_every_meta_carries_its_own_key() -> None: for key, meta in CATALOG.items(): assert isinstance(meta, SettingMeta) assert meta.key == key def test_secrets_are_exactly_the_masked_set() -> None: # LOCKED A4: write-only, masked — the 3 named secrets + # database_url (read-only, but its URL carries credentials). assert set(SECRETS) == { "llm_api_key", "admin_password", "session_secret", "database_url", } def test_non_overridable_is_exactly_locked_a3() -> None: # LOCKED A3: database_url builds the engine that would read the # override (chicken-and-egg brick); embedding_dim is fixed in the # chunks table by A6 (a dim override would corrupt retrieval). assert set(NON_OVERRIDABLE) == {"database_url", "embedding_dim"} def test_restart_required_is_the_boot_wired_set() -> None: # LOCKED A4: logging, the gzip middleware (compress_min_bytes), the # static mount (static_dir), create_engine (db_pool_*), and # SessionMiddleware (session_*). assert set(RESTART_REQUIRED) == { "log_level", "compress_min_bytes", "static_dir", "db_pool_size", "db_pool_max_overflow", "db_pool_recycle", "session_secret", "session_max_age", "session_cookie", } def test_env_var_is_bare_key_upper_prefixed() -> None: assert env_var("relevance_threshold") == "BOR_RELEVANCE_THRESHOLD" for key in CATALOG: assert env_var(key).startswith("BOR_") def test_labels_nonempty_and_unique() -> None: labels = [meta.label for meta in CATALOG.values()] assert all(label.strip() for label in labels), "empty label in the catalogue" duplicates = sorted({label for label in labels if labels.count(label) > 1}) assert not duplicates, f"duplicate labels: {duplicates}"