""" Tests for the IUCLID projection layer. """ from django.test import TestCase, tag from envipy_additional_information.information import Temperature from epdb.logic import PackageManager, UserManager from epdb.models import AdditionalInformation, Pathway, Scenario from epapi.v1.interfaces.iuclid.projections import get_pathway_for_iuclid_export @tag("api", "iuclid") class IUCLIDExportScenarioAITests(TestCase): """Test that scenario additional information is correctly reflected in the IUCLID export.""" @classmethod def setUpTestData(cls): cls.user = UserManager.create_user( "iuclid-test-user", "iuclid-test@envipath.com", "SuperSafe", set_setting=False, add_to_group=False, is_active=True, ) cls.package = PackageManager.create_package( cls.user, "IUCLID Test Package", "Package for IUCLID export tests" ) cls.pathway = Pathway.create(cls.package, "CCO", name="Test Pathway") cls.root_node = cls.pathway.node_set.get(depth=0) cls.compound = cls.root_node.default_node_label.compound cls.scenario = Scenario.objects.create( package=cls.package, name="Test Scenario", scenario_type="biodegradation", scenario_date="2024-01-01", ) cls.root_node.scenarios.add(cls.scenario) def test_scenario_with_no_ai_exports_without_error(self): """Scenario attached to a node but with no AI must export cleanly with empty lists. Regression: previously scenario.parent was accessed here, causing AttributeError. """ result = get_pathway_for_iuclid_export(self.user, self.pathway.uuid) self.assertEqual(len(result.nodes), 1) node = result.nodes[0] self.assertEqual(len(node.scenarios), 1) self.assertEqual(node.scenarios[0].scenario_uuid, self.scenario.uuid) self.assertEqual(node.scenarios[0].additional_info, []) self.assertEqual(node.additional_info, []) def test_direct_scenario_ai_appears_in_export(self): """AI added directly to a scenario (no object binding) must appear in the export DTO.""" ai = Temperature(interval={"start": 20, "end": 25}) AdditionalInformation.create(self.package, ai, scenario=self.scenario) result = get_pathway_for_iuclid_export(self.user, self.pathway.uuid) node = result.nodes[0] self.assertEqual(len(node.scenarios), 1) scenario_dto = node.scenarios[0] self.assertEqual(len(scenario_dto.additional_info), 1) # The same AI must roll up to the node level self.assertEqual(len(node.additional_info), 1) self.assertEqual(node.additional_info[0], scenario_dto.additional_info[0]) def test_object_bound_ai_excluded_from_scenario_direct_info(self): """AI bound to a specific object (object_id set) must not appear in direct scenario info. get_additional_information(direct_only=True) filters object_id__isnull=False. """ ai = Temperature(interval={"start": 10, "end": 15}) AdditionalInformation.create( self.package, ai, scenario=self.scenario, content_object=self.compound ) result = get_pathway_for_iuclid_export(self.user, self.pathway.uuid) node = result.nodes[0] scenario_dto = node.scenarios[0] self.assertEqual(scenario_dto.additional_info, []) self.assertEqual(node.additional_info, [])