Initial commit
This commit is contained in:
352
tests/test_code_mapper.py
Normal file
352
tests/test_code_mapper.py
Normal file
@@ -0,0 +1,352 @@
|
||||
"""
|
||||
Tests for CodeMapper.
|
||||
|
||||
Validates: Requirements 13.2, 13.3
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import yaml
|
||||
|
||||
from src.pipeline_mco_pmsi.referentiels import CodeMapper, CodeMapping
|
||||
|
||||
|
||||
def test_code_mapper_initialization():
|
||||
"""Test CodeMapper initialization."""
|
||||
mapper = CodeMapper()
|
||||
assert mapper.mappings_dir is not None
|
||||
assert len(mapper.cim10_mappings) == 0
|
||||
assert len(mapper.ccam_mappings) == 0
|
||||
|
||||
|
||||
def test_add_mapping():
|
||||
"""
|
||||
Test adding a code mapping.
|
||||
|
||||
Validates: Requirement 13.2
|
||||
"""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapping = CodeMapping(
|
||||
obsolete_code="J45.0",
|
||||
current_code="J45.00",
|
||||
obsolete_label="Asthme à prédominance allergique",
|
||||
current_label="Asthme à prédominance allergique, non précisé",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="split",
|
||||
notes="Code divisé"
|
||||
)
|
||||
|
||||
mapper.add_mapping(mapping, "cim10")
|
||||
|
||||
assert "J45.0" in mapper.cim10_mappings
|
||||
assert mapper.cim10_mappings["J45.0"].current_code == "J45.00"
|
||||
|
||||
|
||||
def test_map_obsolete_code():
|
||||
"""
|
||||
Test mapping an obsolete code to current code.
|
||||
|
||||
Validates: Requirement 13.2
|
||||
"""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapping = CodeMapping(
|
||||
obsolete_code="J45.0",
|
||||
current_code="J45.00",
|
||||
obsolete_label="Asthme",
|
||||
current_label="Asthme précisé",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="split"
|
||||
)
|
||||
|
||||
mapper.add_mapping(mapping, "cim10")
|
||||
|
||||
# Map obsolete code
|
||||
current = mapper.map_code("J45.0", "cim10")
|
||||
assert current == "J45.00"
|
||||
|
||||
# Current code returns None
|
||||
current = mapper.map_code("J45.00", "cim10")
|
||||
assert current is None
|
||||
|
||||
|
||||
def test_add_alias():
|
||||
"""
|
||||
Test adding a code alias.
|
||||
|
||||
Validates: Requirement 13.3
|
||||
"""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapper.add_alias("K29.70", "K29.7", "cim10")
|
||||
|
||||
assert "K29.70" in mapper.cim10_aliases
|
||||
assert mapper.cim10_aliases["K29.70"] == "K29.7"
|
||||
|
||||
|
||||
def test_map_alias_code():
|
||||
"""
|
||||
Test mapping an alias code to canonical code.
|
||||
|
||||
Validates: Requirement 13.3
|
||||
"""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapper.add_alias("K29.70", "K29.7", "cim10")
|
||||
|
||||
# Map alias
|
||||
canonical = mapper.map_code("K29.70", "cim10")
|
||||
assert canonical == "K29.7"
|
||||
|
||||
|
||||
def test_is_obsolete():
|
||||
"""Test checking if a code is obsolete."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapping = CodeMapping(
|
||||
obsolete_code="J45.0",
|
||||
current_code="J45.00",
|
||||
obsolete_label="Asthme",
|
||||
current_label="Asthme précisé",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="split"
|
||||
)
|
||||
|
||||
mapper.add_mapping(mapping, "cim10")
|
||||
|
||||
assert mapper.is_obsolete("J45.0", "cim10") is True
|
||||
assert mapper.is_obsolete("J45.00", "cim10") is False
|
||||
|
||||
|
||||
def test_get_mapping_info():
|
||||
"""Test getting detailed mapping information."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapping = CodeMapping(
|
||||
obsolete_code="J45.0",
|
||||
current_code="J45.00",
|
||||
obsolete_label="Asthme",
|
||||
current_label="Asthme précisé",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="split",
|
||||
notes="Test note"
|
||||
)
|
||||
|
||||
mapper.add_mapping(mapping, "cim10")
|
||||
|
||||
info = mapper.get_mapping_info("J45.0", "cim10")
|
||||
assert info is not None
|
||||
assert info.current_code == "J45.00"
|
||||
assert info.reason == "split"
|
||||
assert info.notes == "Test note"
|
||||
|
||||
|
||||
def test_track_label_change():
|
||||
"""
|
||||
Test tracking label changes.
|
||||
|
||||
Validates: Requirement 13.3
|
||||
"""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapper.track_label_change(
|
||||
code="K29.7",
|
||||
old_label="Gastrite, sans précision",
|
||||
new_label="Gastrite non précisée",
|
||||
referentiel_type="cim10",
|
||||
effective_date=datetime(2024, 1, 1)
|
||||
)
|
||||
|
||||
history = mapper.get_label_history("K29.7", "cim10")
|
||||
assert len(history) == 1
|
||||
assert history[0]["old_label"] == "Gastrite, sans précision"
|
||||
assert history[0]["new_label"] == "Gastrite non précisée"
|
||||
|
||||
|
||||
def test_load_mappings_yaml(tmp_path):
|
||||
"""
|
||||
Test loading mappings from YAML file.
|
||||
|
||||
Validates: Requirement 13.2
|
||||
"""
|
||||
# Create test mapping file
|
||||
mapping_file = tmp_path / "test_mappings.yaml"
|
||||
data = {
|
||||
"referentiel_type": "cim10",
|
||||
"mappings": [
|
||||
{
|
||||
"obsolete_code": "J45.0",
|
||||
"current_code": "J45.00",
|
||||
"obsolete_label": "Asthme",
|
||||
"current_label": "Asthme précisé",
|
||||
"effective_date": "2024-01-01T00:00:00",
|
||||
"reason": "split",
|
||||
"notes": "Test"
|
||||
}
|
||||
],
|
||||
"aliases": [
|
||||
{"alias": "K29.70", "canonical": "K29.7"}
|
||||
]
|
||||
}
|
||||
|
||||
with open(mapping_file, "w") as f:
|
||||
yaml.dump(data, f)
|
||||
|
||||
mapper = CodeMapper()
|
||||
count = mapper.load_mappings("cim10", mapping_file)
|
||||
|
||||
assert count == 1
|
||||
assert "J45.0" in mapper.cim10_mappings
|
||||
assert "K29.70" in mapper.cim10_aliases
|
||||
|
||||
|
||||
def test_save_mappings_yaml(tmp_path):
|
||||
"""Test saving mappings to YAML file."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapping = CodeMapping(
|
||||
obsolete_code="J45.0",
|
||||
current_code="J45.00",
|
||||
obsolete_label="Asthme",
|
||||
current_label="Asthme précisé",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="split"
|
||||
)
|
||||
|
||||
mapper.add_mapping(mapping, "cim10")
|
||||
mapper.add_alias("K29.70", "K29.7", "cim10")
|
||||
|
||||
# Save to file
|
||||
output_file = tmp_path / "output_mappings.yaml"
|
||||
mapper.save_mappings("cim10", output_file)
|
||||
|
||||
assert output_file.exists()
|
||||
|
||||
# Load and verify
|
||||
with open(output_file, "r") as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
assert data["referentiel_type"] == "cim10"
|
||||
assert len(data["mappings"]) == 1
|
||||
assert len(data["aliases"]) == 1
|
||||
|
||||
|
||||
def test_get_statistics():
|
||||
"""Test getting mapping statistics."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
# Add multiple mappings with different reasons
|
||||
mapper.add_mapping(
|
||||
CodeMapping(
|
||||
obsolete_code="J45.0",
|
||||
current_code="J45.00",
|
||||
obsolete_label="Asthme",
|
||||
current_label="Asthme précisé",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="split"
|
||||
),
|
||||
"cim10"
|
||||
)
|
||||
|
||||
mapper.add_mapping(
|
||||
CodeMapping(
|
||||
obsolete_code="I25.1",
|
||||
current_code="I25.10",
|
||||
obsolete_label="Cardiopathie",
|
||||
current_label="Cardiopathie précisée",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="split"
|
||||
),
|
||||
"cim10"
|
||||
)
|
||||
|
||||
mapper.add_mapping(
|
||||
CodeMapping(
|
||||
obsolete_code="K29.0",
|
||||
current_code="K29.00",
|
||||
obsolete_label="Gastrite",
|
||||
current_label="Gastrite aiguë",
|
||||
effective_date=datetime(2024, 1, 1),
|
||||
reason="renamed"
|
||||
),
|
||||
"cim10"
|
||||
)
|
||||
|
||||
mapper.add_alias("K29.70", "K29.7", "cim10")
|
||||
|
||||
stats = mapper.get_statistics("cim10")
|
||||
|
||||
assert stats["total_mappings"] == 3
|
||||
assert stats["total_aliases"] == 1
|
||||
assert stats["mappings_by_reason"]["split"] == 2
|
||||
assert stats["mappings_by_reason"]["renamed"] == 1
|
||||
|
||||
|
||||
def test_ccam_mappings():
|
||||
"""Test CCAM code mappings."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
mapping = CodeMapping(
|
||||
obsolete_code="YYYY001",
|
||||
current_code="YYYY002",
|
||||
obsolete_label="Ancien acte",
|
||||
current_label="Nouvel acte",
|
||||
effective_date=datetime(2025, 1, 1),
|
||||
reason="renamed"
|
||||
)
|
||||
|
||||
mapper.add_mapping(mapping, "ccam")
|
||||
|
||||
assert "YYYY001" in mapper.ccam_mappings
|
||||
assert mapper.map_code("YYYY001", "ccam") == "YYYY002"
|
||||
assert mapper.is_obsolete("YYYY001", "ccam") is True
|
||||
|
||||
|
||||
def test_multiple_label_changes():
|
||||
"""Test tracking multiple label changes for same code."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
# First change
|
||||
mapper.track_label_change(
|
||||
code="K29.7",
|
||||
old_label="Gastrite",
|
||||
new_label="Gastrite, sans précision",
|
||||
referentiel_type="cim10",
|
||||
effective_date=datetime(2023, 1, 1)
|
||||
)
|
||||
|
||||
# Second change
|
||||
mapper.track_label_change(
|
||||
code="K29.7",
|
||||
old_label="Gastrite, sans précision",
|
||||
new_label="Gastrite non précisée",
|
||||
referentiel_type="cim10",
|
||||
effective_date=datetime(2024, 1, 1)
|
||||
)
|
||||
|
||||
history = mapper.get_label_history("K29.7", "cim10")
|
||||
assert len(history) == 2
|
||||
assert history[0]["effective_date"] == "2023-01-01T00:00:00"
|
||||
assert history[1]["effective_date"] == "2024-01-01T00:00:00"
|
||||
|
||||
|
||||
def test_load_nonexistent_file():
|
||||
"""Test loading from nonexistent file raises error."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
with pytest.raises(FileNotFoundError):
|
||||
mapper.load_mappings("cim10", Path("/nonexistent/file.yaml"))
|
||||
|
||||
|
||||
def test_unsupported_file_format(tmp_path):
|
||||
"""Test loading unsupported file format raises error."""
|
||||
mapper = CodeMapper()
|
||||
|
||||
bad_file = tmp_path / "test.txt"
|
||||
bad_file.write_text("test")
|
||||
|
||||
with pytest.raises(ValueError, match="Unsupported file format"):
|
||||
mapper.load_mappings("cim10", bad_file)
|
||||
Reference in New Issue
Block a user