Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CA-258 sort requirements correctly #102

Merged
merged 3 commits into from
Mar 4, 2024
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
22 changes: 16 additions & 6 deletions backend/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,20 +196,29 @@ def get_sorted_requirement_nodes(
requirement_nodes: the list of all requirement_nodes
requirements_assessed: the list of all requirements_assessed
Returns a dictionary containing key=name and value={"description": description, "style": "leaf|node"}}
Values are correctly sorted based on order_id
If order_id is missing, sorting is based on created_at
"""

# cope for old version not creating order_id correctly
for req in requirement_nodes:
if req.order_id is None:
req.order_id = req.created_at

requirement_assessment_from_requirement_id = (
{str(ra.requirement.id): ra for ra in requirements_assessed}
{str(ra.requirement_id): ra for ra in requirements_assessed}
if requirements_assessed
else {}
)


def get_sorted_requirement_nodes_rec(
requirement_nodes: list,
requirements_assessed: list,
start: list,
) -> dict:
"""
Recursive function to build framework groups tree, within get_sorted_requirements_and_groups
Recursive function to build framework groups tree, within get_sorted_requirements_nodes
start: the initial list
"""
result = {}
Expand All @@ -231,11 +240,12 @@ def get_sorted_requirement_nodes_rec(
requirement_nodes, requirements_assessed, children
),
}
for req in [
for req in sorted([
requirement_node
for requirement_node in requirement_nodes
if requirement_node.parent_urn == node.urn
]:
], key=lambda x: x.order_id):

if requirements_assessed:
req_as = requirement_assessment_from_requirement_id[str(req.id)]
result[str(node.id)]["children"][str(req.id)].update(
Expand Down Expand Up @@ -278,9 +288,9 @@ def get_sorted_requirement_nodes_rec(
tree = get_sorted_requirement_nodes_rec(
requirement_nodes,
requirements_assessed,
[rg for rg in requirement_nodes if not rg.parent_urn],
sorted([rn for rn in requirement_nodes if not rn.parent_urn],
key=lambda x: x.order_id),
)

return tree


Expand Down
11 changes: 0 additions & 11 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,17 +284,6 @@ class Meta:
verbose_name = _("Framework")
verbose_name_plural = _("Frameworks")

def get_next_order_id(self, obj_type: models.Model, _parent_urn: str = None) -> int:
"""
Returns the next order id for a given object type
"""
if _parent_urn:
return (
obj_type.objects.filter(framework=self, parent_urn=_parent_urn).count()
+ 1
)
else:
return obj_type.objects.filter(framework=self).count() + 1

def is_deletable(self) -> bool:
"""
Expand Down
6 changes: 3 additions & 3 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,7 @@ def tree(self, request, pk):
_framework = Framework.objects.get(id=pk)
return Response(
get_sorted_requirement_nodes(
RequirementNode.objects.filter(framework=_framework), None
RequirementNode.objects.filter(framework=_framework).all(), None
)
)

Expand Down Expand Up @@ -1181,10 +1181,10 @@ def tree(self, request, pk):
_framework = self.get_object().framework
return Response(
get_sorted_requirement_nodes(
RequirementNode.objects.filter(framework=_framework),
RequirementNode.objects.filter(framework=_framework).all(),
RequirementAssessment.objects.filter(
compliance_assessment=self.get_object()
),
).all(),
)
)

Expand Down
3 changes: 3 additions & 0 deletions backend/library/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ def preview_library(library) -> dict[str, list]:
preview = {}
requirement_nodes_list = []
if library["objects"]["framework"].get("requirement_nodes"):
index=0
for requirement_node in library["objects"]["framework"]["requirement_nodes"]:
index+=1
requirement_nodes_list.append(
RequirementNode(
description=requirement_node.get("description"),
ref_id=requirement_node.get("ref_id"),
name=requirement_node.get("name"),
urn=requirement_node["urn"],
parent_urn=requirement_node.get("parent_urn"),
order_id=index,
)
)
preview["requirement_nodes"] = requirement_nodes_list
Expand Down
7 changes: 4 additions & 3 deletions backend/library/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ def get_library_items(library, type: str) -> list[dict]:
class RequirementNodeImporter:
REQUIRED_FIELDS = {"urn"}

def __init__(self, requirement_data: dict):
def __init__(self, requirement_data: dict, index: int):
self.requirement_data = requirement_data
self.index = index

def is_valid(self) -> Union[str, None]:
if missing_fields := self.REQUIRED_FIELDS - set(self.requirement_data.keys()):
Expand All @@ -121,7 +122,7 @@ def import_requirement_node(self, framework_object: Framework):
ref_id=self.requirement_data.get("ref_id"),
annotation=self.requirement_data.get("annotation"),
provider=framework_object.provider,
order_id=self.requirement_data.get("order_id"),
order_id=self.index,
level=self.requirement_data.get("level"),
name=self.requirement_data.get("name"),
description=self.requirement_data.get("description"),
Expand Down Expand Up @@ -154,7 +155,7 @@ def init_requirement_nodes(self, requirement_nodes: List[dict]) -> Union[str, No
requirement_node_importers = []
import_errors = []
for index, requirement_node_data in enumerate(requirement_nodes):
requirement_node_importer = RequirementNodeImporter(requirement_node_data)
requirement_node_importer = RequirementNodeImporter(requirement_node_data, index)
requirement_node_importers.append(requirement_node_importer)
if (
requirement_node_error := requirement_node_importer.is_valid()
Expand Down
Loading