From ba3a149ec190a789e00df813b275d977f3808b56 Mon Sep 17 00:00:00 2001 From: Thomas Chopitea Date: Sat, 25 May 2024 16:44:56 +0200 Subject: [PATCH] Update indicators when DFIQ Approaches are created via the API (#1080) --- core/web/apiv2/dfiq.py | 9 ++ tests/apiv2/dfiq.py | 134 +++++++++++++++++- .../Q1020.10_no_indicators.yaml | 31 ++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 tests/dfiq_test_data/Q1020.10_no_indicators.yaml diff --git a/core/web/apiv2/dfiq.py b/core/web/apiv2/dfiq.py index 531845d7a..ecaba9cb6 100644 --- a/core/web/apiv2/dfiq.py +++ b/core/web/apiv2/dfiq.py @@ -14,6 +14,7 @@ class NewDFIQRequest(BaseModel): dfiq_yaml: str dfiq_type: dfiq.DFIQType + update_indicators: bool = False class DFIQValidateRequest(NewDFIQRequest): @@ -33,6 +34,7 @@ class PatchDFIQRequest(BaseModel): dfiq_yaml: str dfiq_type: dfiq.DFIQType + update_indicators: bool = False class DFIQSearchRequest(BaseModel): @@ -81,6 +83,9 @@ async def new_from_yaml(request: NewDFIQRequest) -> dfiq.DFIQTypes: except ValueError as error: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(error)) + if request.update_indicators and new.type == dfiq.DFIQType.approach: + dfiq.extract_indicators(new) + return new @@ -124,6 +129,10 @@ async def patch(request: PatchDFIQRequest, dfiq_id) -> dfiq.DFIQTypes: updated_dfiq = db_dfiq.model_copy(update=update_data.model_dump()) new = updated_dfiq.save() new.update_parents() + + if request.update_indicators and new.type == dfiq.DFIQType.approach: + dfiq.extract_indicators(new) + return new diff --git a/tests/apiv2/dfiq.py b/tests/apiv2/dfiq.py index d6612db1d..57078bb45 100644 --- a/tests/apiv2/dfiq.py +++ b/tests/apiv2/dfiq.py @@ -262,7 +262,11 @@ def test_dfiq_patch_approach_updates_parents(self) -> None: approach.dfiq_id = "Q1022.10" response = client.patch( f"/api/v2/dfiq/{approach.id}", - json={"dfiq_yaml": approach.to_yaml(), "dfiq_type": approach.type}, + json={ + "dfiq_yaml": approach.to_yaml(), + "dfiq_type": approach.type, + "update_indicators": False, + }, ) data = response.json() self.assertEqual(response.status_code, 200, data) @@ -276,6 +280,134 @@ def test_dfiq_patch_approach_updates_parents(self) -> None: self.assertEqual(edges[0][0].description, "Uses DFIQ approach") self.assertEqual(total, 1) + def test_dfiq_patch_approach_updates_indicators(self) -> None: + dfiq.DFIQScenario( + name="mock_scenario", + dfiq_id="S1003", + dfiq_version="1.0.0", + description="desc", + dfiq_yaml="mock", + ).save() + + dfiq.DFIQFacet( + name="mock_facet", + dfiq_id="F1005", + dfiq_version="1.0.0", + description="desc", + parent_ids=["S1003"], + dfiq_yaml="mock", + ).save() + + dfiq.DFIQQuestion( + name="mock_question", + dfiq_id="Q1020", + dfiq_version="1.0.0", + description="desc", + parent_ids=["F1005"], + dfiq_yaml="mock", + ).save() + + with open("tests/dfiq_test_data/Q1020.10_no_indicators.yaml", "r") as f: + yaml_string = f.read() + approach = dfiq.DFIQApproach.from_yaml(yaml_string).save() + approach.update_parents() + + vertices, edges, total = approach.neighbors() + self.assertEqual(len(vertices), 1) + self.assertEqual(total, 1) + + with open("tests/dfiq_test_data/Q1020.10.yaml", "r") as f: + yaml_string = f.read() + + response = client.patch( + f"/api/v2/dfiq/{approach.id}", + json={ + "dfiq_yaml": yaml_string, + "dfiq_type": approach.type, + "update_indicators": False, + }, + ) + data = response.json() + self.assertEqual(response.status_code, 200, data) + vertices, edges, total = approach.neighbors() + self.assertEqual(len(vertices), 1) + self.assertEqual(total, 1) + + response = client.patch( + f"/api/v2/dfiq/{approach.id}", + json={ + "dfiq_yaml": yaml_string, + "dfiq_type": approach.type, + "update_indicators": True, + }, + ) + data = response.json() + self.assertEqual(response.status_code, 200, data) + vertices, edges, total = approach.neighbors() + self.assertEqual(len(vertices), 4) + self.assertEqual(total, 4) + + def test_dfiq_post_approach(self): + dfiq.DFIQScenario( + name="mock_scenario", + dfiq_id="S1003", + dfiq_version="1.0.0", + description="desc", + dfiq_yaml="mock", + ).save() + + dfiq.DFIQFacet( + name="mock_facet", + dfiq_id="F1005", + dfiq_version="1.0.0", + description="desc", + parent_ids=["S1003"], + dfiq_yaml="mock", + ).save() + + dfiq.DFIQQuestion( + name="mock_question", + dfiq_id="Q1020", + dfiq_version="1.0.0", + description="desc", + parent_ids=["F1005"], + dfiq_yaml="mock", + ).save() + + with open("tests/dfiq_test_data/Q1020.10.yaml", "r") as f: + yaml_string = f.read() + + response = client.post( + "/api/v2/dfiq/from_yaml", + json={ + "dfiq_yaml": yaml_string, + "dfiq_type": dfiq.DFIQType.approach, + "update_indicators": False, + }, + ) + data = response.json() + self.assertEqual(response.status_code, 200, data) + + approach = dfiq.DFIQApproach.get(id=data["id"]) + vertices, edges, total = approach.neighbors() + self.assertEqual(len(vertices), 1) + approach.delete() + + response = client.post( + "/api/v2/dfiq/from_yaml", + json={ + "dfiq_yaml": yaml_string, + "dfiq_type": dfiq.DFIQType.approach, + "update_indicators": True, + }, + ) + data = response.json() + self.assertEqual(response.status_code, 200, data) + + approach = dfiq.DFIQApproach.get(id=data["id"]) + vertices, edges, total = approach.neighbors() + self.assertEqual(len(vertices), 4) + def test_wrong_parent(self) -> None: with open("tests/dfiq_test_data/F1005.yaml", "r") as f: yaml_string = f.read() diff --git a/tests/dfiq_test_data/Q1020.10_no_indicators.yaml b/tests/dfiq_test_data/Q1020.10_no_indicators.yaml new file mode 100644 index 000000000..293f05efe --- /dev/null +++ b/tests/dfiq_test_data/Q1020.10_no_indicators.yaml @@ -0,0 +1,31 @@ +--- +display_name: Approach1 +type: approach +id: Q1020.10 +dfiq_version: 1.0.0 +tags: + - Lots + - Of + - Tags +description: + summary: Description for approach + details: > + Details for approach + references: + - "ref1" + - "ref2" + references_internal: null +view: + data: + - type: artifact + value: RandomArtifact + - type: description + value: Random description + notes: + covered: + - Covered1 + - Covered2 + - Covered3 + not_covered: + - Not covered1 + - Not covered2