148 lines
4.3 KiB
Python
148 lines
4.3 KiB
Python
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]
|