78 lines
3.4 KiB
Python
78 lines
3.4 KiB
Python
import pytest
|
|
from app.modules.design.domain.entities import (
|
|
Capability,
|
|
Entity,
|
|
Module,
|
|
TraceabilityLink,
|
|
)
|
|
from app.modules.design.domain.services import DesignValidationService
|
|
from app.modules.design.domain.value_objects import FileStatus
|
|
|
|
|
|
class TestFileStatusDetermination:
|
|
def test_empty_content_is_missing(self):
|
|
assert DesignValidationService.determine_file_status("", "test.csv") == FileStatus.MISSING
|
|
|
|
def test_csv_header_only_is_sparse(self):
|
|
assert DesignValidationService.determine_file_status("id,name\n", "test.csv") == FileStatus.SPARSE
|
|
|
|
def test_csv_with_data_is_ok(self):
|
|
content = "id,name\n1,foo\n2,bar\n"
|
|
assert DesignValidationService.determine_file_status(content, "test.csv") == FileStatus.OK
|
|
|
|
def test_md_too_short_is_sparse(self):
|
|
assert DesignValidationService.determine_file_status("# Title\n\nShort.\n", "test.md") == FileStatus.SPARSE
|
|
|
|
def test_template_residue_detected(self):
|
|
content = "id,name\nTODO,<replace this>\nreal,data\n"
|
|
assert DesignValidationService.determine_file_status(content, "test.csv") == FileStatus.TEMPLATE_RESIDUE
|
|
|
|
def test_placeholder_heavy(self):
|
|
content = "id,name,desc\nTODO,TODO,TODO\nTODO,TODO,TODO\n"
|
|
assert DesignValidationService.determine_file_status(content, "test.csv") == FileStatus.PLACEHOLDER_HEAVY
|
|
|
|
def test_ok_md_file(self):
|
|
content = "---\ndoc_id: DOC-01\ntitle: Test\n---\n\n# Title\n\nThis is a real document with enough content.\nLine 4.\nLine 5.\nLine 6.\n"
|
|
assert DesignValidationService.determine_file_status(content, "test.md") == FileStatus.OK
|
|
|
|
|
|
class TestConstraintValidation:
|
|
def _make_cap(self, cap_id: str) -> Capability:
|
|
return Capability(cap_id, "n", "d", "must", "MVP", [])
|
|
|
|
def _make_mod(self, mod_id: str) -> Module:
|
|
return Module(mod_id, "n", "backend", "d", "MVP", [], [])
|
|
|
|
def _make_ent(self, ent_id: str, owner: str) -> Entity:
|
|
return Entity(ent_id, "n", "d", owner, "d", "MVP", "f.csv")
|
|
|
|
def _make_link(self, trace_id: str, cap: str, mod: str, ents: list[str]) -> TraceabilityLink:
|
|
return TraceabilityLink(trace_id, cap, mod, ents, [], "")
|
|
|
|
def test_capability_without_module_link_is_violation(self):
|
|
caps = [self._make_cap("CAP-01")]
|
|
links = []
|
|
violations = DesignValidationService.check_capability_module_linkage(caps, links)
|
|
assert len(violations) == 1
|
|
|
|
def test_entity_without_owner_is_violation(self):
|
|
entities = [self._make_ent("ENT-01", "")]
|
|
violations = DesignValidationService.check_entity_owner(entities)
|
|
assert len(violations) == 1
|
|
|
|
def test_valid_traceability_passes(self):
|
|
caps = [self._make_cap("CAP-01")]
|
|
mods = [self._make_mod("MOD-01")]
|
|
ents = [self._make_ent("ENT-01", "MOD-01")]
|
|
links = [self._make_link("TR-01", "CAP-01", "MOD-01", ["ENT-01"])]
|
|
violations = DesignValidationService.check_traceability_references(links, caps, mods, ents)
|
|
assert len(violations) == 0
|
|
|
|
def test_broken_traceability_reference_is_violation(self):
|
|
caps = [self._make_cap("CAP-01")]
|
|
mods = [self._make_mod("MOD-01")]
|
|
ents = [self._make_ent("ENT-01", "MOD-01")]
|
|
links = [self._make_link("TR-01", "CAP-MISSING", "MOD-01", ["ENT-01"])]
|
|
violations = DesignValidationService.check_traceability_references(links, caps, mods, ents)
|
|
assert len(violations) >= 1
|