Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,7 @@ def get_extensible_codelist_mappings(self):
for item in items:
if hasattr(item, "ExtendedValue") and item.ExtendedValue == "Yes":
extended_values.append(item.CodedValue)
if (
extended_values
and hasattr(codelist, "Alias")
and codelist.Alias is not None
):
if extended_values and hasattr(codelist, "Alias") and codelist.Alias:
mappings[codelist.Name] = {
"codelist": codelist.Alias[0].Name,
"extended_values": extended_values,
Expand Down
66 changes: 66 additions & 0 deletions tests/unit/test_define_xml_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from cdisc_rules_engine.services.define_xml.define_xml_reader_2_0 import (
DefineXMLReader20,
)
from unittest.mock import MagicMock

resources_path: Path = Path(__file__).parent.parent.joinpath("resources")
test_define_2_0_file_path: Path = resources_path.joinpath("test_defineV20-SDTM.xml")
Expand Down Expand Up @@ -434,3 +435,68 @@ def test_extract_domain_metadata_nv_has_no_data(filename, has_no_data):
# Check that at least one expected variable is present
for v in ["NVSEQ", "NVTESTCD", "NVTEST"]:
assert v in domain_metadata["define_dataset_variables"]


class TestGetExtensibleCodelistMappings:
@staticmethod
def _make_codelist(name, coded_values_extended, alias_list):
"""Helper to build a mock CodeList object."""
codelist = MagicMock()
codelist.Name = name

items = []
for value, is_extended in coded_values_extended:
item = MagicMock()
item.CodedValue = value
item.ExtendedValue = "Yes" if is_extended else "No"
items.append(item)
codelist.CodeListItem = items
codelist.Alias = alias_list

return codelist

@staticmethod
def _make_instance(codelists):
"""Create a minimal object with the method under test and mock loader."""
instance = MagicMock()
instance._odm_loader.MetaDataVersion.return_value.CodeList = codelists

# Bind the real method to the mock instance
from types import MethodType

instance.get_extensible_codelist_mappings = MethodType(
DefineXMLReader21.get_extensible_codelist_mappings, instance
)
return instance

def test_empty_alias_list_is_skipped_without_error(self):
"""A codelist with extended values but Alias=[] must not raise and must be excluded."""
alias = MagicMock()
alias.Name = "C12345"

codelists = [
self._make_codelist("CodelistA", [("VAL1", True)], alias_list=[]),
self._make_codelist("CodelistB", [("VAL2", True)], alias_list=[alias]),
]

instance = self._make_instance(codelists)
result = instance.get_extensible_codelist_mappings()

assert "CodelistA" not in result, "Codelist with empty Alias should be excluded"
assert "CodelistB" in result
assert result["CodelistB"] == {
"codelist": "C12345",
"extended_values": ["VAL2"],
}

def test_none_alias_is_skipped_without_error(self):
"""A codelist where Alias is None must not raise and must be excluded."""
codelists = [
self._make_codelist("CodelistC", [("VAL3", True)], alias_list=None),
]

instance = self._make_instance(codelists)

result = instance.get_extensible_codelist_mappings()

assert result == {}, "Codelist with None Alias should produce an empty mapping"
Loading