Skip to content

Commit

Permalink
Ca 616 serialize requirement node fields in requirement assessment (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ab-smith authored Nov 30, 2024
2 parents ba95c9c + 10ae382 commit 0961b1e
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 30 deletions.
86 changes: 84 additions & 2 deletions backend/app_tests/api/test_api_requirement_assessments.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,48 @@ def test_get_requirement_assessments(self, test):
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
"requirement": {
"str": str(RequirementNode.objects.all()[0]),
"id": str(RequirementNode.objects.all()[0].id),
"urn": RequirementNode.objects.all()[0].urn,
"annotation": RequirementNode.objects.all()[0].annotation,
"name": RequirementNode.objects.all()[0].name,
"description": RequirementNode.objects.all()[0].description,
"typical_evidence": RequirementNode.objects.all()[
0
].typical_evidence,
"ref_id": RequirementNode.objects.all()[0].ref_id,
"associated_reference_controls": RequirementNode.objects.all()[
0
].associated_reference_controls,
"associated_threats": RequirementNode.objects.all()[
0
].associated_threats,
"parent_requirement": {
"str": RequirementNode.objects.all()[0].parent_requirement.get(
"str"
),
"urn": RequirementNode.objects.all()[0].parent_requirement.get(
"urn"
),
"id": str(
RequirementNode.objects.all()[0].parent_requirement.get(
"id"
)
),
"ref_id": RequirementNode.objects.all()[
0
].parent_requirement.get("ref_id"),
"name": RequirementNode.objects.all()[0].parent_requirement.get(
"name"
),
"description": RequirementNode.objects.all()[
0
].parent_requirement.get("description"),
}
if RequirementNode.objects.all()[0].parent_requirement
else None,
},
},
base_count=-1,
user_group=test.user_group,
Expand Down Expand Up @@ -210,7 +251,48 @@ def test_update_requirement_assessments(self, test):
"id": str(compliance_assessment.id),
"str": compliance_assessment.name,
},
"requirement": str(RequirementNode.objects.all()[0].id),
"requirement": {
"str": str(RequirementNode.objects.all()[0]),
"id": str(RequirementNode.objects.all()[0].id),
"urn": RequirementNode.objects.all()[0].urn,
"annotation": RequirementNode.objects.all()[0].annotation,
"name": RequirementNode.objects.all()[0].name,
"description": RequirementNode.objects.all()[0].description,
"typical_evidence": RequirementNode.objects.all()[
0
].typical_evidence,
"ref_id": RequirementNode.objects.all()[0].ref_id,
"associated_reference_controls": RequirementNode.objects.all()[
0
].associated_reference_controls,
"associated_threats": RequirementNode.objects.all()[
0
].associated_threats,
"parent_requirement": {
"str": RequirementNode.objects.all()[0].parent_requirement.get(
"str"
),
"urn": RequirementNode.objects.all()[0].parent_requirement.get(
"urn"
),
"id": str(
RequirementNode.objects.all()[0].parent_requirement.get(
"id"
)
),
"ref_id": RequirementNode.objects.all()[
0
].parent_requirement.get("ref_id"),
"name": RequirementNode.objects.all()[0].parent_requirement.get(
"name"
),
"description": RequirementNode.objects.all()[
0
].parent_requirement.get("description"),
}
if RequirementNode.objects.all()[0].parent_requirement
else None,
},
},
user_group=test.user_group,
)
Expand Down
34 changes: 34 additions & 0 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,40 @@ class RequirementNode(ReferentialObjectMixin, I18nObjectMixin):
)
question = models.JSONField(blank=True, null=True, verbose_name=_("Question"))

@property
def associated_reference_controls(self):
_reference_controls = self.reference_controls.all()
reference_controls = []
for control in _reference_controls:
reference_controls.append(
{"str": control.display_long, "urn": control.urn, "id": control.id}
)
return reference_controls

@property
def associated_threats(self):
_threats = self.threats.all()
threats = []
for control in _threats:
threats.append(
{"str": control.display_long, "urn": control.urn, "id": control.id}
)
return threats

@property
def parent_requirement(self):
parent_requirement = RequirementNode.objects.filter(urn=self.parent_urn).first()
if not parent_requirement:
return None
return {
"str": parent_requirement.display_long,
"urn": parent_requirement.urn,
"id": parent_requirement.id,
"ref_id": parent_requirement.ref_id,
"name": parent_requirement.name,
"description": parent_requirement.description,
}

class Meta:
verbose_name = _("RequirementNode")
verbose_name_plural = _("RequirementNodes")
Expand Down
14 changes: 14 additions & 0 deletions backend/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,20 @@ class RequirementAssessmentReadSerializer(BaseModelSerializer):
compliance_assessment = FieldsRelatedField()
folder = FieldsRelatedField()
assessable = serializers.BooleanField(source="requirement.assessable")
requirement = FieldsRelatedField(
[
"id",
"urn",
"annotation",
"name",
"description",
"typical_evidence",
"ref_id",
"associated_reference_controls",
"associated_threats",
"parent_requirement",
]
)

class Meta:
model = RequirementAssessment
Expand Down
1 change: 0 additions & 1 deletion backend/core/startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@
"view_complianceassessment",
"view_requirementassessment",
"change_requirementassessment",
"view_requirementnode",
"view_evidence",
"add_evidence",
"change_evidence",
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/lib/utils/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,11 @@ export const URL_MODEL_MAP: ModelMap = {
verboseNamePlural: 'Evidences',
fileFields: ['attachment'],
foreignKeyFields: [
{ field: 'folder', urlModel: 'folders', urlParams: 'content_type=DO&content_type=GL' },
{
field: 'folder',
urlModel: 'folders',
urlParams: 'content_type=DO&content_type=GL&content_type=EN'
},
{ field: 'applied_controls', urlModel: 'applied-controls' }
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
const requirementHashmap = Object.fromEntries(
data.requirements.map((requirement) => [requirement.id, requirement])
);
$: requirement = requirementHashmap[currentRequirementAssessment.requirement];
$: requirement = requirementHashmap[currentRequirementAssessment.requirement.id];
$: parent = data.requirements.find((req) => req.urn === requirement.parent_urn);
$: title = requirement.display_short
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,8 @@ export const load = (async ({ fetch, params }) => {
const complianceAssessmentScore = await fetch(
`${BASE_API_URL}/compliance-assessments/${requirementAssessment.compliance_assessment.id}/global_score/`
).then((res) => res.json());
const requirement = await fetch(
`${BASE_API_URL}/requirement-nodes/${requirementAssessment.requirement}/`
).then((res) => res.json());
const parentRequirementNodeEndpoint = `${BASE_API_URL}/requirement-nodes/?urn=${requirement.parent_urn}`;
const parent = await fetch(parentRequirementNodeEndpoint)
.then((res) => res.json())
.then((res) => res.results[0]);
const requirement = requirementAssessment.requirement;
const parent = requirementAssessment.requirement.parent_requirement;

const tables: Record<string, any> = {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
import { page } from '$app/stores';
export let data: PageData;
const threats = data.requirement.threats;
const reference_controls = data.requirement.reference_controls;
const threats = data.requirementAssessment.requirement.associated_threats ?? [];
const reference_controls =
data.requirementAssessment.requirement.associated_reference_controls ?? [];
const annotation = data.requirement.annotation;
const typical_evidence = data.requirement.typical_evidence;
const has_threats = threats && threats.length > 0;
const has_reference_controls = reference_controls && reference_controls.length > 0;
const has_threats = threats.length > 0;
const has_reference_controls = reference_controls.length > 0;
$: mappingInference = {
sourceRequirementAssessment:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,12 @@ export const load = (async ({ fetch, params }) => {
}

const requirementAssessment = await fetchJson(endpoint);
const [compliance_assessment_score, requirement] = await Promise.all([
fetchJson(
`${baseUrl}/compliance-assessments/${requirementAssessment.compliance_assessment.id}/global_score/`
),
fetchJson(`${baseUrl}/requirement-nodes/${requirementAssessment.requirement}/`)
]);

const parent = await fetchJson(
`${baseUrl}/requirement-nodes/?urn=${requirement.parent_urn}`
).then((res) => res.results[0]);
const requirement = requirementAssessment.requirement;
const compliance_assessment_score = await fetchJson(
`${baseUrl}/compliance-assessments/${requirementAssessment.compliance_assessment.id}/global_score/`
);

const parent = requirementAssessment.requirement.parent_requirement;

const model = getModelInfo(URLModel);
const object = { ...requirementAssessment };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
export let data: PageData;
export let form: ActionData;
const threats = data.requirement.threats;
const reference_controls = data.requirement.reference_controls;
const threats = data.requirementAssessment.requirement.associated_threats ?? [];
const reference_controls =
data.requirementAssessment.requirement.associated_reference_controls ?? [];
const annotation = data.requirement.annotation;
const typical_evidence = data.requirement.typical_evidence;
const has_threats = threats && threats.length > 0;
const has_reference_controls = reference_controls && reference_controls.length > 0;
const has_threats = threats.length > 0;
const has_reference_controls = reference_controls.length > 0;
import { page } from '$app/stores';
import AutocompleteSelect from '$lib/components/Forms/AutocompleteSelect.svelte';
Expand Down

0 comments on commit 0961b1e

Please sign in to comment.