backend/tests/test_config_literal_settings.py
Rama master · réplica de lectura del repositorio original.
"""PUT /config rejects values outside a setting's declared choices.
``reload_settings`` overlays saved values with ``model_copy`` (no
validation), so a ``Literal[...]`` on ``UISettings`` never guarded what the
API stored. The track variant policy settings are the Literal fields today;
the check derives the allowed values from the field itself, so a future
Literal setting is covered without touching the route.
"""
import pytest
def test_every_literal_setting_is_checked():
from routes.config.bounds import literal_choices
assert literal_choices("cleanup_track_variant_mode") == {"all", "one_per_language"}
assert literal_choices("cleanup_sidecar_policy") == {"keep_embedded", "drop_if_real_sidecar"}
assert literal_choices("foreign_track_sweep_budget_s") is None
@pytest.mark.parametrize(
"key,value",
[
("cleanup_track_variant_mode", "one_track"),
("cleanup_track_variant_mode", ""),
("cleanup_track_variant_mode", 1),
("cleanup_sidecar_policy", "drop"),
("cleanup_sidecar_policy", None),
],
)
def test_a_value_outside_the_choices_is_rejected_and_nothing_saved(client, key, value):
from db.config import get_config_entry
with client.application.app_context():
before = get_config_entry("cleanup_keep_sdh")
response = client.put("/api/v1/config", json={"cleanup_keep_sdh": True, key: value})
assert response.status_code == 400, response.get_json()
assert key in response.get_json()["error"]
with client.application.app_context():
assert get_config_entry("cleanup_keep_sdh") == before
@pytest.mark.parametrize(
"key,value",
[
("cleanup_track_variant_mode", "one_per_language"),
("cleanup_track_variant_mode", "all"),
("cleanup_sidecar_policy", "drop_if_real_sidecar"),
],
)
def test_a_valid_choice_roundtrips(client, key, value):
response = client.put("/api/v1/config", json={key: value})
assert response.status_code == 200, response.get_json()
assert response.get_json()["config"][key] == value
def test_an_optional_literal_setting_is_checked_too(monkeypatch):
"""``Literal[...] | None`` is a Union, not a Literal: its choices are the
literal values plus None."""
from typing import Literal
from pydantic.fields import FieldInfo
from config_settings import UISettings
from routes.config.bounds import literal_choices, literal_keys
monkeypatch.setitem(
UISettings.model_fields,
"zz_optional_mode",
FieldInfo(annotation=Literal["a", "b"] | None, default=None),
)
assert literal_choices("zz_optional_mode") == {"a", "b", None}
assert "zz_optional_mode" in literal_keys()
# --- POST /config/import (night review I2) ---------------------------------------
def test_import_skips_a_literal_value_outside_the_choices(client):
"""An import saved any writable key as a string; a bad Literal value then
broke reload_settings for everything. It is skipped and reported."""
from db.config import get_config_entry
response = client.post(
"/api/v1/config/import",
json={
"cleanup_track_variant_mode": "one_track",
"cleanup_sidecar_policy": "drop_if_real_sidecar",
},
)
assert response.status_code == 200, response.get_json()
body = response.get_json()
assert "cleanup_track_variant_mode" not in body["imported_keys"]
assert "cleanup_sidecar_policy" in body["imported_keys"]
skipped = {e["key"]: e["error"] for e in body["skipped_invalid"]}
assert "cleanup_track_variant_mode" in skipped
assert "one_per_language" in skipped["cleanup_track_variant_mode"]
with client.application.app_context():
assert get_config_entry("cleanup_track_variant_mode") != "one_track"
assert get_config_entry("cleanup_sidecar_policy") == "drop_if_real_sidecar"
@pytest.mark.parametrize("value", ["5", 10**9, "abc", True])
def test_import_skips_an_out_of_range_sweep_budget(client, value):
from db.config import get_config_entry
response = client.post("/api/v1/config/import", json={"foreign_track_sweep_budget_s": value})
assert response.status_code == 200, response.get_json()
body = response.get_json()
assert "foreign_track_sweep_budget_s" not in body["imported_keys"]
assert [e["key"] for e in body["skipped_invalid"]] == ["foreign_track_sweep_budget_s"]
with client.application.app_context():
assert get_config_entry("foreign_track_sweep_budget_s") != str(value)
def test_import_saves_a_valid_sweep_budget_as_an_integer(client):
from db.config import get_config_entry
response = client.post("/api/v1/config/import", json={"foreign_track_sweep_budget_s": " 900 "})
assert response.status_code == 200, response.get_json()
assert "foreign_track_sweep_budget_s" in response.get_json()["imported_keys"]
with client.application.app_context():
assert get_config_entry("foreign_track_sweep_budget_s") == "900"