Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
6001459
feat(converter): create base_cisu_converter class
Clemsazert Nov 6, 2025
870c9b1
refactor(converter): use BaseCisuConverter for CISUV3Converter
Clemsazert Nov 6, 2025
c7564f8
refactor(converter): extract message related methods
Clemsazert Nov 6, 2025
4e21b74
chore(converter): cache github api requests in tests
Clemsazert Nov 7, 2025
870eb89
refactor(converter): extract function to compute message direction
Clemsazert Nov 7, 2025
4373982
refactor(converter): move & rename create case cisu converter
Clemsazert Nov 7, 2025
6bee7cd
feat(converter): add default resourceInfo converter
Clemsazert Nov 7, 2025
6d7c8f7
chore(converter): generate branch coverage
Clemsazert Nov 7, 2025
51e2281
doc(converter): add instructions to invalidate tests cache
Clemsazert Nov 7, 2025
4a72d93
chore(converter): add missing typing
Clemsazert Nov 7, 2025
90335bb
chore(converter): extract dev dependancies in pyproject.toml
Clemsazert Nov 7, 2025
c6f39ec
style(converter): use absolute imports
Clemsazert Nov 7, 2025
21dac11
refactor(converter): invert dependencies between base message convert…
SimonClo Nov 7, 2025
3c742fe
refactor(converter): base cisu converter inherits from conversion mixin
SimonClo Nov 7, 2025
e363642
refactor(converter): move cisu tests in dedicated folder
SimonClo Nov 7, 2025
6a8861f
refactor(converter): resources info cisu to rs conversion
SimonClo Nov 7, 2025
811c7f7
feat(converter): rs to cisu conversion for resources info message
SimonClo Nov 12, 2025
4a6e062
Merge pull request #326 from ansforge/feat/rc-ri-conversion
SimonClo Nov 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions converter/converter/cisu/cisu_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
translate_key_words,
)

from .base_cisu_converter import BaseCISUConverter

class CISUConverterV3:

class CISUConverterV3(BaseCISUConverter):
"""Handles CISU format conversions"""

CISU_PATHS_TO_DELETE = [
Expand Down Expand Up @@ -70,7 +72,15 @@ class CISUConverterV3:
DEFAULT_WHATS_HAPPEN = {"code": "C11.06.00", "label": "Autre nature de fait"}

@classmethod
def from_cisu(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
def get_rs_message_type(cls) -> str:
return "createCaseHealth"

@classmethod
def get_cisu_message_type(cls) -> str:
return "createCase"

@classmethod
def from_cisu_to_rs(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
"""
Convert from CISU to Health format

Expand Down Expand Up @@ -219,7 +229,7 @@ def get_victim_count(cls, json_data: Dict[str, Any]):
return {"count": "BEAUCOUP"}

@classmethod
def to_cisu(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
def from_rs_to_cisu(cls, input_json: Dict[str, Any]) -> Dict[str, Any]:
"""
Convert from Health to CISU format

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def cisu_conversion_strategy(edxl_json, source_version, target_version):
else:
direction = CISUConstants.FROM_CISU

message_content = extract_message_content(edxl_json)
selected_strategy = select_conversion_strategy(message_content)

if direction == CISUConstants.TO_CISU:
if target_version != CISUConstants.MAINTAINED_CISU_VERSION:
raise ValueError(
Expand All @@ -33,16 +36,50 @@ def cisu_conversion_strategy(edxl_json, source_version, target_version):
rs_json_message = health_conversion_strategy(
edxl_json, source_version, CISUConstants.MAINTAINED_CISU_VERSION
)
return CISUConverterV3.to_cisu(rs_json_message)

return selected_strategy.from_rs_to_cisu(rs_json_message)
elif direction == CISUConstants.FROM_CISU:
if source_version != CISUConstants.MAINTAINED_CISU_VERSION:
raise ValueError(
f"Unknown source version {source_version}. Must be: {CISUConstants.MAINTAINED_CISU_VERSION}"
)

rc_json_message = CISUConverterV3.from_cisu(edxl_json)
rc_json_message = selected_strategy.from_cisu_to_rs(edxl_json)
return health_conversion_strategy(
rc_json_message, CISUConstants.MAINTAINED_CISU_VERSION, target_version
Comment on lines 45 to 46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pour rompre le lien ici, au lieu de faire un if/else binaire dans conversion_strategy on ferait deux if successifs:

message = copy(edxl_json)
if is_cisu_conversion:
  message = cisu_conversion_strategy(message, ...)
if health_conversion_needed:
  message = health_conversion_strategy(message, ...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(dépasse le cadre de cette PR)

)
else:
raise ValueError("Invalid direction parameter")


def extract_message_content(edxl_json):
return (
edxl_json.get("content", [{}])[0]
.get("jsonContent", {})
.get("embeddedJsonContent", {})
.get("message", {})
)


unwanted_keys = ["messageId", "sender", "sentAt", "kind", "status", "recipient"]


def select_conversion_strategy(message_content):
if "createCase" in message_content or "createCaseHealth" in message_content:
return CISUConverterV3
else:
deducted_message_type = extract_message_type_from_message_content(
message_content
)
raise ValueError(
f"Perimeter translation for message type '{deducted_message_type}' is not implemented."
)


def extract_message_type_from_message_content(message_content):
filtered_keys = list(
filter(lambda key: key not in unwanted_keys, message_content.keys())
)
if len(filtered_keys) == 0:
return "unknownMessageType"
return filtered_keys[0]
34 changes: 17 additions & 17 deletions converter/tests/test_cisu_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def validate_health_format(result):
TestHelper.conversion_tests_runner(
sample_dir=TestConstants.RC_EDA_TAG,
envelope_file=TestConstants.EDXL_FIRE_TO_HEALTH_ENVELOPE_PATH,
converter_method=CISUConverterV3.from_cisu,
converter_method=CISUConverterV3.from_cisu_to_rs,
target_schema=RS_EDA_SCHEMA,
additional_validation=validate_health_format,
)
Expand All @@ -33,7 +33,7 @@ def test_to_cisu_conversion_local():
TestHelper.conversion_tests_runner(
sample_dir=TestConstants.RS_EDA_TAG,
envelope_file=TestConstants.EDXL_HEALTH_TO_FIRE_ENVELOPE_PATH,
converter_method=CISUConverterV3.to_cisu,
converter_method=CISUConverterV3.from_rs_to_cisu,
target_schema=RC_EDA_SCHEMA,
)

Expand All @@ -47,7 +47,7 @@ def validate_health_format(result):
TestHelper.conversion_tests_runner(
sample_dir=TestConstants.RC_EDA_TAG,
envelope_file=TestConstants.EDXL_FIRE_TO_HEALTH_ENVELOPE_PATH,
converter_method=CISUConverterV3.from_cisu,
converter_method=CISUConverterV3.from_cisu_to_rs,
target_schema=RS_EDA_SCHEMA,
additional_validation=validate_health_format,
online_tag="main", # ToDo: migrate to "v3" once tag is available
Expand All @@ -59,7 +59,7 @@ def test_to_cisu_conversion_v3():
TestHelper.conversion_tests_runner(
sample_dir=TestConstants.RS_EDA_TAG,
envelope_file=TestConstants.EDXL_HEALTH_TO_FIRE_ENVELOPE_PATH,
converter_method=CISUConverterV3.to_cisu,
converter_method=CISUConverterV3.from_rs_to_cisu,
target_schema=RC_EDA_SCHEMA,
online_tag="main", # ToDo: migrate to "v3" once tag is available
)
Expand Down Expand Up @@ -87,9 +87,9 @@ def test_snapshot_RS_EDA_exhaustive_message(self, mock_choices, mock_now):
self.edxl_envelope_health_to_fire_path,
self.fixtures_folder_path + "RS-EDA/cisu_case/RS-EDA_exhaustive_fill.json",
)
converter = CISUConverterV3()
converter = CISUConverterV3

output_data = converter.to_cisu(message)
output_data = converter.from_rs_to_cisu(message)
self.assertMatchSnapshot(json.dumps(output_data, indent=2))

@patch("converter.cisu.cisu_converter.random")
Expand All @@ -100,9 +100,9 @@ def test_snapshot_RC_EDA_exhaustive_message(self, mock_choices):
self.edxl_envelope_fire_to_health_path,
self.fixtures_folder_path + "RC-EDA/RC-EDA_exhaustive_fill.json",
)
converter = CISUConverterV3()
converter = CISUConverterV3

output_data = converter.from_cisu(message)
output_data = converter.from_cisu_to_rs(message)
self.assertMatchSnapshot(json.dumps(output_data, indent=2))

@patch("converter.cisu.cisu_converter.datetime")
Expand All @@ -117,9 +117,9 @@ def test_snapshot_RS_EDA_required_field_message(self, mock_choices, mock_now):
self.edxl_envelope_health_to_fire_path,
self.fixtures_folder_path + "RS-EDA/cisu_case/RS-EDA_required_fields.json",
)
converter = CISUConverterV3()
converter = CISUConverterV3

output_data = converter.to_cisu(message)
output_data = converter.from_rs_to_cisu(message)
self.assertMatchSnapshot(json.dumps(output_data, indent=2))

@patch("converter.cisu.cisu_converter.random")
Expand All @@ -130,9 +130,9 @@ def test_snapshot_RC_EDA_required_field_message(self, mock_choices):
self.edxl_envelope_fire_to_health_path,
self.fixtures_folder_path + "RC-EDA/RC-EDA_required_fields.json",
)
converter = CISUConverterV3()
converter = CISUConverterV3

output_data = converter.from_cisu(message)
output_data = converter.from_cisu_to_rs(message)

self.assertMatchSnapshot(json.dumps(output_data, indent=2))

Expand All @@ -149,9 +149,9 @@ def test_snapshot_RS_EDA_exhaustive_bis_message(self, mock_choices, mock_now):
self.fixtures_folder_path
+ "RS-EDA/cisu_case/RS-EDA_exhaustive_fill_bis.json",
)
converter = CISUConverterV3()
converter = CISUConverterV3

output_data = converter.to_cisu(message)
output_data = converter.from_rs_to_cisu(message)
self.assertMatchSnapshot(json.dumps(output_data, indent=2))

@patch("converter.cisu.cisu_converter.random")
Expand All @@ -162,17 +162,17 @@ def test_snapshot_RC_EDA_exhaustive_bis_message(self, mock_choices):
self.edxl_envelope_fire_to_health_path,
self.fixtures_folder_path + "RC-EDA/RC-EDA_exhaustive_fill_bis.json",
)
converter = CISUConverterV3()
converter = CISUConverterV3

output_data = converter.from_cisu(message)
output_data = converter.from_cisu_to_rs(message)

self.assertMatchSnapshot(json.dumps(output_data, indent=2))


class TestVictimsCount(TestCase):
def setUp(self):
self.fixtures_folder_path = "tests/fixtures/"
self.converter = CISUConverterV3()
self.converter = CISUConverterV3

def test_count_victims_1(self):
patients = TestHelper.load_json_file(
Expand Down