Skip to content

Commit

Permalink
fix: Fix backlinks
Browse files Browse the repository at this point in the history
Merge pull request #103 from DSD-DBS/fix-backlinks
  • Loading branch information
ewuerger authored Aug 29, 2024
2 parents 9f498f2 + 1dc591a commit 04e3ea9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 52 deletions.
48 changes: 25 additions & 23 deletions capella2polarion/converters/link_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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,
Expand Down Expand Up @@ -293,29 +299,25 @@ def _create_link_fields(

def create_grouped_back_link_fields(
self,
data: data_session.ConverterData,
links: list[polarion_api.WorkItemLink],
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 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(
Expand Down
4 changes: 2 additions & 2 deletions capella2polarion/converters/model_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
)
88 changes: 61 additions & 27 deletions tests/test_elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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():
Expand All @@ -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(
Expand All @@ -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,
Expand All @@ -1360,7 +1398,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
Expand All @@ -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"
Expand All @@ -1401,30 +1438,27 @@ 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"),
]
link_serializer.create_grouped_back_link_fields(converter_data, links)
links = {
"attribute_reverse": [
polarion_api.WorkItemLink("prim1", "id", "role1"),
polarion_api.WorkItemLink("prim2", "id", "role1"),
]
}
assert (wi := converter_data.work_item) is not None
link_serializer.create_grouped_back_link_fields(wi, links)

check_sum = work_item.calculate_checksum()

links = [
polarion_api.WorkItemLink("prim2", "id", "role1"),
polarion_api.WorkItemLink("prim1", "id", "role1"),
]
link_serializer.create_grouped_back_link_fields(converter_data, links)
links = {
"attribute_reverse": [
polarion_api.WorkItemLink("prim2", "id", "role1"),
polarion_api.WorkItemLink("prim1", "id", "role1"),
]
}
link_serializer.create_grouped_back_link_fields(work_item, links)

assert check_sum == work_item.calculate_checksum()

Expand Down

0 comments on commit 04e3ea9

Please sign in to comment.