From 197753e303c1dfca23cd932ee5205082f70889ab Mon Sep 17 00:00:00 2001 From: Michael Harbarth Date: Thu, 29 Aug 2024 08:18:34 +0200 Subject: [PATCH 1/2] fix: backlink generation --- capella2polarion/converters/link_converter.py | 40 ++++++++++--------- .../converters/model_converter.py | 2 +- tests/test_elements.py | 34 +++++++--------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/capella2polarion/converters/link_converter.py b/capella2polarion/converters/link_converter.py index d5f185a3..197f2e76 100644 --- a/capella2polarion/converters/link_converter.py +++ b/capella2polarion/converters/link_converter.py @@ -196,7 +196,9 @@ def _create( def create_grouped_link_fields( self, data: data_session.ConverterData, - back_links: dict[str, list[polarion_api.WorkItemLink]] | None = None, + back_links: ( + dict[str, dict[str, list[polarion_api.WorkItemLink]]] | None + ) = None, ): """Create the grouped link fields from the primary work item. @@ -216,16 +218,20 @@ def create_grouped_link_fields( for role, grouped_links in _group_by( "role", work_item.linked_work_items ).items(): - if back_links is not None: - for link in grouped_links: - key = link.secondary_work_item_id - back_links.setdefault(key, []).append(link) - - config = find_link_config(data, role) - if config is not None and config.link_field: - self._create_link_fields( - work_item, config.link_field, grouped_links, config=config - ) + if (config := find_link_config(data, role)) is not None: + if back_links is not None and config.reverse_field: + for link in grouped_links: + back_links.setdefault( + link.secondary_work_item_id, {} + ).setdefault(config.reverse_field, []).append(link) + + if config.link_field: + self._create_link_fields( + work_item, + config.link_field, + grouped_links, + config=config, + ) def _create_link_fields( self, @@ -294,7 +300,7 @@ def _create_link_fields( def create_grouped_back_link_fields( self, data: data_session.ConverterData, - links: list[polarion_api.WorkItemLink], + links: dict[str, list[polarion_api.WorkItemLink]], ): """Create fields for the given WorkItem using a list of backlinks. @@ -310,12 +316,10 @@ def create_grouped_back_link_fields( assert work_item is not None wi = f"[{work_item.id}]({work_item.type} {work_item.title})" logger.debug("Building grouped back links for work item %r...", wi) - for role, grouped_links in _group_by("role", links).items(): - config = find_link_config(data, role) - if config is not None and config.reverse_field: - self._create_link_fields( - work_item, config.reverse_field, grouped_links, True - ) + for reverse_field, grouped_links in links.items(): + self._create_link_fields( + work_item, reverse_field, grouped_links, True + ) def find_link_config( diff --git a/capella2polarion/converters/model_converter.py b/capella2polarion/converters/model_converter.py index 4336966b..f7d6bf59 100644 --- a/capella2polarion/converters/model_converter.py +++ b/capella2polarion/converters/model_converter.py @@ -122,7 +122,7 @@ def generate_work_item_links( polarion_data_repo: polarion_repo.PolarionDataRepository, ): """Generate links for all work items and add custom fields for them.""" - back_links: dict[str, list[polarion_api.WorkItemLink]] = {} + back_links: dict[str, dict[str, list[polarion_api.WorkItemLink]]] = {} link_serializer = link_converter.LinkSerializer( polarion_data_repo, self.converter_session, diff --git a/tests/test_elements.py b/tests/test_elements.py index 0975dccd..d5ce06c4 100644 --- a/tests/test_elements.py +++ b/tests/test_elements.py @@ -1288,7 +1288,7 @@ def test_grouped_links_attributes_with_includes( base_object.pw.polarion_params.project_id, base_object.c2pcli.capella_model, ) - backlinks: dict[str, list[polarion_api.WorkItemLink]] = {} + backlinks: dict[str, dict[str, list[polarion_api.WorkItemLink]]] = {} work_item = ( base_object.pw.polarion_data_repo.get_work_item_by_capella_uuid( fnc.uuid @@ -1318,7 +1318,7 @@ def test_maintain_reverse_grouped_links_attributes( link_serializer = grouped_links_base_object["link_serializer"] dummy_work_items = grouped_links_base_object["work_items"] config = grouped_links_base_object["config"] - back_links: dict[str, list[polarion_api.WorkItemLink]] = {} + back_links: dict[str, dict[str, list[polarion_api.WorkItemLink]]] = {} data = {} for work_item in dummy_work_items.values(): @@ -1360,7 +1360,7 @@ def test_maintain_reverse_grouped_links_attributes_with_role_prefix( dummy_work_items = grouped_links_base_object["work_items"] config = grouped_links_base_object["config"] config.links[0].polarion_role = f"_C2P_{config.links[0].polarion_role}" - back_links: dict[str, list[polarion_api.WorkItemLink]] = {} + back_links: dict[str, dict[str, list[polarion_api.WorkItemLink]]] = {} data = {} for link in ( dummy_work_items["uuid0"].linked_work_items @@ -1401,29 +1401,25 @@ def test_grouped_linked_work_items_order_consistency( ) config = converter_config.CapellaTypeConfig( "fakeModelObject", - links=[ - converter_config.LinkConfig( - capella_attr="attribute", - polarion_role="role1", - link_field="attribute1", - reverse_field="attribute_reverse", - ) - ], ) work_item = data_models.CapellaWorkItem("id", "Dummy") converter_data = data_session.ConverterData("test", config, [], work_item) - links = [ - polarion_api.WorkItemLink("prim1", "id", "role1"), - polarion_api.WorkItemLink("prim2", "id", "role1"), - ] + links = { + "attribute_reverse": [ + polarion_api.WorkItemLink("prim1", "id", "role1"), + polarion_api.WorkItemLink("prim2", "id", "role1"), + ] + } link_serializer.create_grouped_back_link_fields(converter_data, links) check_sum = work_item.calculate_checksum() - links = [ - polarion_api.WorkItemLink("prim2", "id", "role1"), - polarion_api.WorkItemLink("prim1", "id", "role1"), - ] + links = { + "attribute_reverse": [ + polarion_api.WorkItemLink("prim2", "id", "role1"), + polarion_api.WorkItemLink("prim1", "id", "role1"), + ] + } link_serializer.create_grouped_back_link_fields(converter_data, links) assert check_sum == work_item.calculate_checksum() From 1dc591a392ca8ff5797e2d03d56c97e6ed32ad03 Mon Sep 17 00:00:00 2001 From: Michael Harbarth Date: Thu, 29 Aug 2024 08:48:42 +0200 Subject: [PATCH 2/2] test: add test and minor refactoring --- capella2polarion/converters/link_converter.py | 8 ++- .../converters/model_converter.py | 2 +- tests/test_elements.py | 54 ++++++++++++++++--- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/capella2polarion/converters/link_converter.py b/capella2polarion/converters/link_converter.py index 197f2e76..bf8bb511 100644 --- a/capella2polarion/converters/link_converter.py +++ b/capella2polarion/converters/link_converter.py @@ -299,21 +299,19 @@ def _create_link_fields( def create_grouped_back_link_fields( self, - data: data_session.ConverterData, + work_item: data_models.CapellaWorkItem, links: dict[str, list[polarion_api.WorkItemLink]], ): """Create fields for the given WorkItem using a list of backlinks. Parameters ---------- - data + work_item The ConverterData that stores the WorkItem to create the fields for. links - List of links referencing work_item as secondary. + Dict of field names and links referencing work_item as secondary. """ - work_item = data.work_item - assert work_item is not None wi = f"[{work_item.id}]({work_item.type} {work_item.title})" logger.debug("Building grouped back links for work item %r...", wi) for reverse_field, grouped_links in links.items(): diff --git a/capella2polarion/converters/model_converter.py b/capella2polarion/converters/model_converter.py index f7d6bf59..d7c79b38 100644 --- a/capella2polarion/converters/model_converter.py +++ b/capella2polarion/converters/model_converter.py @@ -155,5 +155,5 @@ def generate_work_item_links( assert converter_data.work_item.id is not None if local_back_links := back_links.get(converter_data.work_item.id): link_serializer.create_grouped_back_link_fields( - converter_data, local_back_links + converter_data.work_item, local_back_links ) diff --git a/tests/test_elements.py b/tests/test_elements.py index d5ce06c4..fc19f1c5 100644 --- a/tests/test_elements.py +++ b/tests/test_elements.py @@ -1329,9 +1329,8 @@ def test_maintain_reverse_grouped_links_attributes( converter_data, back_links ) for work_item_id, links in back_links.items(): - link_serializer.create_grouped_back_link_fields( - data[work_item_id], links - ) + assert (wi := data[work_item_id].work_item) is not None + link_serializer.create_grouped_back_link_fields(wi, links) assert ( dummy_work_items["uuid0"].additional_attributes.pop( @@ -1352,6 +1351,45 @@ def test_maintain_reverse_grouped_links_attributes( == HTML_LINK_2["attribute_reverse"] ) + @staticmethod + def test_maintain_reverse_grouped_links_unidirectional_config( + grouped_links_base_object: GroupedLinksBaseObject, + ): + link_serializer = grouped_links_base_object["link_serializer"] + dummy_work_items = grouped_links_base_object["work_items"] + config = grouped_links_base_object["config"] + back_links: dict[str, dict[str, list[polarion_api.WorkItemLink]]] = {} + data = {} + + for work_item in dummy_work_items.values(): + data[work_item.id] = converter_data = data_session.ConverterData( + "test", + config, + FakeModelObject(work_item.uuid_capella), + work_item, + ) + link_serializer.create_grouped_link_fields( + converter_data, back_links + ) + # Only the first work item needs the link config + config.links = [] + for work_item_id, links in back_links.items(): + assert (wi := data[work_item_id].work_item) is not None + link_serializer.create_grouped_back_link_fields(wi, links) + + assert ( + "attribute_reverse" + not in dummy_work_items["uuid0"].additional_attributes + ) + assert ( + "attribute_reverse" + in dummy_work_items["uuid1"].additional_attributes + ) + assert ( + "attribute_reverse" + in dummy_work_items["uuid2"].additional_attributes + ) + @staticmethod def test_maintain_reverse_grouped_links_attributes_with_role_prefix( grouped_links_base_object: GroupedLinksBaseObject, @@ -1376,9 +1414,8 @@ def test_maintain_reverse_grouped_links_attributes_with_role_prefix( converter_data, back_links ) for work_item_id, links in back_links.items(): - link_serializer.create_grouped_back_link_fields( - data[work_item_id], links - ) + assert (wi := data[work_item_id].work_item) is not None + link_serializer.create_grouped_back_link_fields(wi, links) assert ( "attribute_reverse" @@ -1410,7 +1447,8 @@ def test_grouped_linked_work_items_order_consistency( polarion_api.WorkItemLink("prim2", "id", "role1"), ] } - link_serializer.create_grouped_back_link_fields(converter_data, links) + assert (wi := converter_data.work_item) is not None + link_serializer.create_grouped_back_link_fields(wi, links) check_sum = work_item.calculate_checksum() @@ -1420,7 +1458,7 @@ def test_grouped_linked_work_items_order_consistency( polarion_api.WorkItemLink("prim1", "id", "role1"), ] } - link_serializer.create_grouped_back_link_fields(converter_data, links) + link_serializer.create_grouped_back_link_fields(work_item, links) assert check_sum == work_item.calculate_checksum()