forked from enviPath/enviPy
[Fix] Iuclid export produce only one root substance (#429)
Reviewed-on: enviPath/enviPy#429 Co-authored-by: Tobias O <tobias.olenyi@envipath.com> Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
This commit is contained in:
@ -120,13 +120,6 @@ class PathwayMapper:
|
||||
)
|
||||
bundle.reference_substances.append(ref_sub)
|
||||
|
||||
sub = IUCLIDSubstanceData(
|
||||
uuid=sub_uuid,
|
||||
name=compound.name,
|
||||
reference_substance_uuid=ref_sub_uuid,
|
||||
)
|
||||
bundle.substances.append(sub)
|
||||
|
||||
if not export.compounds:
|
||||
return bundle
|
||||
|
||||
@ -145,6 +138,16 @@ class PathwayMapper:
|
||||
if not root_compound_pks:
|
||||
return bundle
|
||||
|
||||
for root_pk in root_compound_pks:
|
||||
root_sub_uuid, root_ref_uuid = seen_compounds[root_pk]
|
||||
bundle.substances.append(
|
||||
IUCLIDSubstanceData(
|
||||
uuid=root_sub_uuid,
|
||||
name=compound_names[root_pk],
|
||||
reference_substance_uuid=root_ref_uuid,
|
||||
)
|
||||
)
|
||||
|
||||
edge_templates: list[tuple[UUID, frozenset[int], tuple[int, ...], tuple[UUID, ...]]] = []
|
||||
for edge in sorted(export.edges, key=lambda item: str(item.edge_uuid)):
|
||||
parent_compound_pks = sorted(
|
||||
|
||||
@ -70,8 +70,7 @@ class IUCLIDExportAPITest(TestCase):
|
||||
names = zf.namelist()
|
||||
self.assertIn("manifest.xml", names)
|
||||
i6d_files = [n for n in names if n.endswith(".i6d")]
|
||||
# 2 substances + 2 ref substances + 1 ESR = 5 i6d files
|
||||
self.assertEqual(len(i6d_files), 5)
|
||||
self.assertEqual(len(i6d_files), 4)
|
||||
|
||||
def test_anonymous_returns_401(self):
|
||||
self.client.logout()
|
||||
|
||||
@ -7,6 +7,11 @@ from uuid import uuid4
|
||||
|
||||
from django.test import SimpleTestCase, tag
|
||||
|
||||
from epapi.v1.interfaces.iuclid.dto import (
|
||||
PathwayCompoundDTO,
|
||||
PathwayEdgeDTO,
|
||||
PathwayExportDTO,
|
||||
)
|
||||
from epiuclid.serializers.i6z import I6ZSerializer
|
||||
from epiuclid.serializers.pathway_mapper import (
|
||||
IUCLIDDocumentBundle,
|
||||
@ -14,9 +19,24 @@ from epiuclid.serializers.pathway_mapper import (
|
||||
IUCLIDReferenceSubstanceData,
|
||||
IUCLIDSubstanceData,
|
||||
IUCLIDTransformationProductEntry,
|
||||
PathwayMapper,
|
||||
)
|
||||
|
||||
|
||||
def _unlinked_documents(manifest_xml: str) -> list[tuple[str | None, str]]:
|
||||
ns = "http://iuclid6.echa.europa.eu/namespaces/manifest/v1"
|
||||
root = ET.fromstring(manifest_xml)
|
||||
base = root.findtext(f"{{{ns}}}base-document-uuid")
|
||||
linked_targets: set[str | None] = {base}
|
||||
docs: dict[str, str | None] = {}
|
||||
for doc in root.findall(f".//{{{ns}}}document"):
|
||||
uuid = doc.findtext(f"{{{ns}}}uuid")
|
||||
docs[uuid] = doc.findtext(f"{{{ns}}}type")
|
||||
for link in doc.findall(f"{{{ns}}}links/{{{ns}}}link"):
|
||||
linked_targets.add(link.findtext(f"{{{ns}}}ref-uuid"))
|
||||
return [(doc_type, uuid) for uuid, doc_type in docs.items() if uuid not in linked_targets]
|
||||
|
||||
|
||||
def _make_bundle() -> IUCLIDDocumentBundle:
|
||||
ref_uuid = uuid4()
|
||||
sub_uuid = uuid4()
|
||||
@ -197,3 +217,29 @@ class I6ZSerializerTest(SimpleTestCase):
|
||||
}
|
||||
self.assertIn(parent_ref_key, reference_links)
|
||||
self.assertIn(product_ref_key, reference_links)
|
||||
|
||||
def test_multi_compound_pathway_has_no_unlinked_documents(self):
|
||||
compounds = [
|
||||
PathwayCompoundDTO(pk=1, name="Root", smiles="c1ccccc1"),
|
||||
PathwayCompoundDTO(pk=2, name="P1", smiles="CCO"),
|
||||
PathwayCompoundDTO(pk=3, name="P2", smiles="CCN"),
|
||||
PathwayCompoundDTO(pk=4, name="P3", smiles="CCC"),
|
||||
]
|
||||
export = PathwayExportDTO(
|
||||
pathway_uuid=uuid4(),
|
||||
pathway_name="Regression Pathway",
|
||||
compounds=compounds,
|
||||
edges=[
|
||||
PathwayEdgeDTO(edge_uuid=uuid4(), start_compound_pks=[1], end_compound_pks=[2]),
|
||||
PathwayEdgeDTO(edge_uuid=uuid4(), start_compound_pks=[1], end_compound_pks=[3]),
|
||||
PathwayEdgeDTO(edge_uuid=uuid4(), start_compound_pks=[2], end_compound_pks=[4]),
|
||||
],
|
||||
root_compound_pks=[1],
|
||||
)
|
||||
bundle = PathwayMapper().map(export)
|
||||
data = I6ZSerializer().serialize(bundle)
|
||||
|
||||
with zipfile.ZipFile(io.BytesIO(data)) as zf:
|
||||
manifest_xml = zf.read("manifest.xml").decode("utf-8")
|
||||
|
||||
self.assertEqual(_unlinked_documents(manifest_xml), [])
|
||||
|
||||
@ -31,7 +31,7 @@ class PathwayMapperTest(SimpleTestCase):
|
||||
)
|
||||
bundle = PathwayMapper().map(export)
|
||||
|
||||
self.assertEqual(len(bundle.substances), 2)
|
||||
self.assertEqual(len(bundle.substances), 1)
|
||||
self.assertEqual(len(bundle.reference_substances), 2)
|
||||
self.assertEqual(len(bundle.endpoint_study_records), 1)
|
||||
|
||||
@ -49,8 +49,7 @@ class PathwayMapperTest(SimpleTestCase):
|
||||
)
|
||||
bundle = PathwayMapper().map(export)
|
||||
|
||||
# 2 unique compounds -> 2 substances, 2 ref substances
|
||||
self.assertEqual(len(bundle.substances), 2)
|
||||
self.assertEqual(len(bundle.substances), 1)
|
||||
self.assertEqual(len(bundle.reference_substances), 2)
|
||||
# One endpoint study record per pathway
|
||||
self.assertEqual(len(bundle.endpoint_study_records), 1)
|
||||
|
||||
Reference in New Issue
Block a user