feat: cache Ollama + parallélisation ThreadPool + filtrage DAS renforcé + modules GHM/CPAM/export RUM
- Cache persistant JSON thread-safe pour les résultats Ollama (invalidation par modèle) - Parallélisation des appels Ollama (ThreadPoolExecutor, 2 workers) - 6 nouvelles règles de filtrage DAS parasites (doublons, ponctuation, OCR, labo, fragments) - Client Ollama centralisé (mode JSON natif + retry) - Module GHM (estimation CMD/sévérité) - Module contrôle CPAM (parser + contre-argumentation RAG) - Export RUM (format RSS) - Viewer enrichi (détail dossier) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
212
tests/test_rum_export.py
Normal file
212
tests/test_rum_export.py
Normal file
@@ -0,0 +1,212 @@
|
||||
"""Tests pour le module d'export RUM V016."""
|
||||
|
||||
import pytest
|
||||
|
||||
from src.config import ActeCCAM, Diagnostic, DossierMedical, Sejour
|
||||
from src.export.rum_export import (
|
||||
RUMConfig,
|
||||
export_rum,
|
||||
_format_cim10,
|
||||
_format_date,
|
||||
_format_sex,
|
||||
_format_ccam_act,
|
||||
_map_mode_entree,
|
||||
_map_mode_sortie,
|
||||
)
|
||||
|
||||
|
||||
class TestFormatHelpers:
|
||||
def test_format_cim10_normal(self):
|
||||
assert _format_cim10("K85.1") == "K851 "
|
||||
assert len(_format_cim10("K85.1")) == 8
|
||||
|
||||
def test_format_cim10_short(self):
|
||||
result = _format_cim10("J18")
|
||||
assert result == "J18 "
|
||||
assert len(result) == 8
|
||||
|
||||
def test_format_cim10_none(self):
|
||||
assert _format_cim10(None) == " "
|
||||
assert len(_format_cim10(None)) == 8
|
||||
|
||||
def test_format_cim10_empty(self):
|
||||
assert _format_cim10("") == " "
|
||||
|
||||
def test_format_date_ddmmyyyy(self):
|
||||
assert _format_date("15/03/2025") == "15032025"
|
||||
|
||||
def test_format_date_iso(self):
|
||||
assert _format_date("2025-03-15") == "15032025"
|
||||
|
||||
def test_format_date_none(self):
|
||||
assert _format_date(None) == " "
|
||||
assert len(_format_date(None)) == 8
|
||||
|
||||
def test_format_sex_masculin(self):
|
||||
assert _format_sex("M") == "1"
|
||||
assert _format_sex("Masculin") == "1"
|
||||
assert _format_sex("H") == "1"
|
||||
|
||||
def test_format_sex_feminin(self):
|
||||
assert _format_sex("F") == "2"
|
||||
assert _format_sex("Féminin") == "2"
|
||||
|
||||
def test_format_sex_none(self):
|
||||
assert _format_sex(None) == " "
|
||||
|
||||
def test_map_mode_entree(self):
|
||||
assert _map_mode_entree("Domicile") == "8"
|
||||
assert _map_mode_entree("Mutation") == "6"
|
||||
assert _map_mode_entree("Transfert") == "7"
|
||||
assert _map_mode_entree(None) == " "
|
||||
|
||||
def test_map_mode_sortie(self):
|
||||
assert _map_mode_sortie("Domicile") == "8"
|
||||
assert _map_mode_sortie("Décès") == "9"
|
||||
assert _map_mode_sortie("Transfert") == "7"
|
||||
assert _map_mode_sortie(None) == " "
|
||||
|
||||
def test_format_ccam_act(self):
|
||||
acte = ActeCCAM(texte="Cholécystectomie", code_ccam_suggestion="HMFC004", date="15/03/2025")
|
||||
result = _format_ccam_act(acte)
|
||||
assert len(result) == 29
|
||||
assert result[:7] == "HMFC004"
|
||||
assert result[7] == "1" # phase
|
||||
assert result[8] == "1" # activité
|
||||
assert result[9:17] == "15032025" # date
|
||||
|
||||
|
||||
class TestExportRUM:
|
||||
def _make_dossier(self, **kwargs):
|
||||
defaults = dict(
|
||||
source_file="test.pdf",
|
||||
sejour=Sejour(
|
||||
sexe="M",
|
||||
date_entree="01/01/2025",
|
||||
date_sortie="05/01/2025",
|
||||
mode_entree="Domicile",
|
||||
mode_sortie="Domicile",
|
||||
),
|
||||
diagnostic_principal=Diagnostic(texte="Pneumonie", cim10_suggestion="J18.9"),
|
||||
diagnostics_associes=[
|
||||
Diagnostic(texte="HTA", cim10_suggestion="I10"),
|
||||
],
|
||||
actes_ccam=[
|
||||
ActeCCAM(texte="Radio thorax", code_ccam_suggestion="ZBQK002", date="02/01/2025"),
|
||||
],
|
||||
)
|
||||
defaults.update(kwargs)
|
||||
return DossierMedical(**defaults)
|
||||
|
||||
def test_fixed_zone_length(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
# La zone fixe fait 165 chars, plus DAS et actes
|
||||
assert len(rum) >= 165
|
||||
|
||||
def test_fixed_zone_exact_165(self):
|
||||
dossier = self._make_dossier(diagnostics_associes=[], actes_ccam=[])
|
||||
rum = export_rum(dossier)
|
||||
assert len(rum) == 165
|
||||
|
||||
def test_version_format(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
assert rum[9:12] == "016" # version format
|
||||
assert rum[24:27] == "016" # version RUM
|
||||
|
||||
def test_finess(self):
|
||||
config = RUMConfig(finess="123456789")
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier, config)
|
||||
assert rum[15:24] == "123456789"
|
||||
|
||||
def test_sexe(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
assert rum[85] == "1" # M
|
||||
|
||||
def test_dates(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
assert rum[92:100] == "01012025" # date entrée
|
||||
assert rum[102:110] == "05012025" # date sortie
|
||||
|
||||
def test_modes(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
assert rum[100] == "8" # mode entrée domicile
|
||||
assert rum[110] == "8" # mode sortie domicile
|
||||
|
||||
def test_dp_field(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
assert rum[131:139] == "J189 "
|
||||
|
||||
def test_nb_das(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
assert rum[125:127] == "01"
|
||||
|
||||
def test_nb_actes(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
assert rum[129:131] == "01"
|
||||
|
||||
def test_das_variable_zone(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
# DAS commence à pos 165, 8 chars
|
||||
das_zone = rum[165:173]
|
||||
assert das_zone == "I10 "
|
||||
|
||||
def test_acte_variable_zone(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
# 1 DAS (8 chars) puis l'acte (29 chars) à pos 173
|
||||
acte_zone = rum[173:202]
|
||||
assert len(acte_zone) == 29
|
||||
assert acte_zone[:7] == "ZBQK002"
|
||||
|
||||
def test_total_length(self):
|
||||
dossier = self._make_dossier()
|
||||
rum = export_rum(dossier)
|
||||
# 165 + 1*8 (DAS) + 1*29 (acte) = 202
|
||||
assert len(rum) == 202
|
||||
|
||||
|
||||
class TestEdgeCases:
|
||||
def test_no_dp(self):
|
||||
dossier = DossierMedical(source_file="test.pdf")
|
||||
rum = export_rum(dossier)
|
||||
assert len(rum) == 165
|
||||
assert rum[131:139] == " "
|
||||
|
||||
def test_no_sejour_data(self):
|
||||
dossier = DossierMedical(
|
||||
source_file="test.pdf",
|
||||
diagnostic_principal=Diagnostic(texte="Test", cim10_suggestion="J18.9"),
|
||||
)
|
||||
rum = export_rum(dossier)
|
||||
assert len(rum) == 165
|
||||
assert rum[85] == " " # sexe vide
|
||||
|
||||
def test_multiple_das_and_actes(self):
|
||||
dossier = DossierMedical(
|
||||
source_file="test.pdf",
|
||||
diagnostic_principal=Diagnostic(texte="Test", cim10_suggestion="K85.1"),
|
||||
diagnostics_associes=[
|
||||
Diagnostic(texte="D1", cim10_suggestion="I10"),
|
||||
Diagnostic(texte="D2", cim10_suggestion="E11.9"),
|
||||
Diagnostic(texte="D3", cim10_suggestion="I48.9"),
|
||||
],
|
||||
actes_ccam=[
|
||||
ActeCCAM(texte="A1", code_ccam_suggestion="HMFC004", date="01/01/2025"),
|
||||
ActeCCAM(texte="A2", code_ccam_suggestion="ZBQK002", date="02/01/2025"),
|
||||
],
|
||||
)
|
||||
rum = export_rum(dossier)
|
||||
# 165 + 3*8 + 2*29 = 165 + 24 + 58 = 247
|
||||
assert len(rum) == 247
|
||||
assert rum[125:127] == "03" # nb DAS
|
||||
assert rum[129:131] == "02" # nb actes
|
||||
Reference in New Issue
Block a user