from pathlib import Path import pytest from mka.application.glossary import GlossaryRepository from mka.application.glossary_yaml import ( GlossaryYamlError, export_glossary_yaml, import_glossary_yaml, ) def repository(tmp_path: Path) -> GlossaryRepository: result = GlossaryRepository(tmp_path / "glossary.sqlite3") result.initialize() return result def test_round_trip_preserves_ids_aliases_and_active_state(tmp_path: Path) -> None: source = repository(tmp_path / "source") active = source.create( "Größenmaß", "technical_term", aliases=("Groessenmass", "Größen-Maß"), description="Canonical UTF-8 spelling", ) inactive = source.create("Legacy Product", "product", is_active=False) encoded = export_glossary_yaml(source.list()).encode("utf-8") target = repository(tmp_path / "target") target.create("Will be replaced", "other") target.replace_all(import_glossary_yaml(encoded)) entries = target.list() assert [entry.id for entry in entries] == [active.id, inactive.id] assert entries[0].canonical_term == "Größenmaß" assert entries[0].aliases == ("Groessenmass", "Größen-Maß") assert entries[0].description == "Canonical UTF-8 spelling" assert entries[0].is_active is True assert entries[1].is_active is False def test_malformed_yaml_does_not_replace_existing_glossary(tmp_path: Path) -> None: glossary = repository(tmp_path) existing = glossary.create("PBAT", "acronym") with pytest.raises(GlossaryYamlError, match="Malformed glossary YAML"): import_glossary_yaml(b"version: 1\nglossary: [") assert glossary.list() == [existing] @pytest.mark.parametrize( "entries, message", [ ( [ { "id": 1, "canonical_term": "PBAT", "aliases": [], "category": "acronym", "description": None, "active": True, }, { "id": 2, "canonical_term": "pbat", "aliases": [], "category": "material", "description": None, "active": True, }, ], "duplicate canonical term or alias", ), ( [ { "id": 1, "canonical_term": "Secugrid", "aliases": ["Sikirgut", "SIKIRGUT"], "category": "product", "description": None, "active": True, }, ], "aliases must be unique", ), ( [ { "id": 1, "canonical_term": "Secugrid", "aliases": ["PBAT"], "category": "product", "description": None, "active": True, }, { "id": 2, "canonical_term": "PBAT", "aliases": [], "category": "acronym", "description": None, "active": False, }, ], "duplicate canonical term or alias", ), ], ) def test_duplicate_terms_and_aliases_are_rejected( entries: list[dict[str, object]], message: str ) -> None: import yaml content = yaml.safe_dump({"version": 1, "glossary": entries}) with pytest.raises(GlossaryYamlError, match=message): import_glossary_yaml(content) def test_validation_failure_leaves_database_unchanged(tmp_path: Path) -> None: glossary = repository(tmp_path) existing = glossary.create("Existing", "other", aliases=("Existing alias",)) invalid = b"""version: 1 glossary: - id: 10 canonical_term: Duplicate aliases: [] category: other description: null active: true - id: 11 canonical_term: duplicate aliases: [] category: other description: null active: false """ with pytest.raises(GlossaryYamlError): imported = import_glossary_yaml(invalid) glossary.replace_all(imported) assert glossary.list() == [existing]