Skip to content

Commit ba3a149

Browse files
authored
Update indicators when DFIQ Approaches are created via the API (#1080)
1 parent f25981e commit ba3a149

File tree

3 files changed

+173
-1
lines changed

3 files changed

+173
-1
lines changed

core/web/apiv2/dfiq.py

+9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class NewDFIQRequest(BaseModel):
1414

1515
dfiq_yaml: str
1616
dfiq_type: dfiq.DFIQType
17+
update_indicators: bool = False
1718

1819

1920
class DFIQValidateRequest(NewDFIQRequest):
@@ -33,6 +34,7 @@ class PatchDFIQRequest(BaseModel):
3334

3435
dfiq_yaml: str
3536
dfiq_type: dfiq.DFIQType
37+
update_indicators: bool = False
3638

3739

3840
class DFIQSearchRequest(BaseModel):
@@ -81,6 +83,9 @@ async def new_from_yaml(request: NewDFIQRequest) -> dfiq.DFIQTypes:
8183
except ValueError as error:
8284
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(error))
8385

86+
if request.update_indicators and new.type == dfiq.DFIQType.approach:
87+
dfiq.extract_indicators(new)
88+
8489
return new
8590

8691

@@ -124,6 +129,10 @@ async def patch(request: PatchDFIQRequest, dfiq_id) -> dfiq.DFIQTypes:
124129
updated_dfiq = db_dfiq.model_copy(update=update_data.model_dump())
125130
new = updated_dfiq.save()
126131
new.update_parents()
132+
133+
if request.update_indicators and new.type == dfiq.DFIQType.approach:
134+
dfiq.extract_indicators(new)
135+
127136
return new
128137

129138

tests/apiv2/dfiq.py

+133-1
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,11 @@ def test_dfiq_patch_approach_updates_parents(self) -> None:
262262
approach.dfiq_id = "Q1022.10"
263263
response = client.patch(
264264
f"/api/v2/dfiq/{approach.id}",
265-
json={"dfiq_yaml": approach.to_yaml(), "dfiq_type": approach.type},
265+
json={
266+
"dfiq_yaml": approach.to_yaml(),
267+
"dfiq_type": approach.type,
268+
"update_indicators": False,
269+
},
266270
)
267271
data = response.json()
268272
self.assertEqual(response.status_code, 200, data)
@@ -276,6 +280,134 @@ def test_dfiq_patch_approach_updates_parents(self) -> None:
276280
self.assertEqual(edges[0][0].description, "Uses DFIQ approach")
277281
self.assertEqual(total, 1)
278282

283+
def test_dfiq_patch_approach_updates_indicators(self) -> None:
284+
dfiq.DFIQScenario(
285+
name="mock_scenario",
286+
dfiq_id="S1003",
287+
dfiq_version="1.0.0",
288+
description="desc",
289+
dfiq_yaml="mock",
290+
).save()
291+
292+
dfiq.DFIQFacet(
293+
name="mock_facet",
294+
dfiq_id="F1005",
295+
dfiq_version="1.0.0",
296+
description="desc",
297+
parent_ids=["S1003"],
298+
dfiq_yaml="mock",
299+
).save()
300+
301+
dfiq.DFIQQuestion(
302+
name="mock_question",
303+
dfiq_id="Q1020",
304+
dfiq_version="1.0.0",
305+
description="desc",
306+
parent_ids=["F1005"],
307+
dfiq_yaml="mock",
308+
).save()
309+
310+
with open("tests/dfiq_test_data/Q1020.10_no_indicators.yaml", "r") as f:
311+
yaml_string = f.read()
312+
approach = dfiq.DFIQApproach.from_yaml(yaml_string).save()
313+
approach.update_parents()
314+
315+
vertices, edges, total = approach.neighbors()
316+
self.assertEqual(len(vertices), 1)
317+
self.assertEqual(total, 1)
318+
319+
with open("tests/dfiq_test_data/Q1020.10.yaml", "r") as f:
320+
yaml_string = f.read()
321+
322+
response = client.patch(
323+
f"/api/v2/dfiq/{approach.id}",
324+
json={
325+
"dfiq_yaml": yaml_string,
326+
"dfiq_type": approach.type,
327+
"update_indicators": False,
328+
},
329+
)
330+
data = response.json()
331+
self.assertEqual(response.status_code, 200, data)
332+
vertices, edges, total = approach.neighbors()
333+
self.assertEqual(len(vertices), 1)
334+
self.assertEqual(total, 1)
335+
336+
response = client.patch(
337+
f"/api/v2/dfiq/{approach.id}",
338+
json={
339+
"dfiq_yaml": yaml_string,
340+
"dfiq_type": approach.type,
341+
"update_indicators": True,
342+
},
343+
)
344+
data = response.json()
345+
self.assertEqual(response.status_code, 200, data)
346+
vertices, edges, total = approach.neighbors()
347+
self.assertEqual(len(vertices), 4)
348+
self.assertEqual(total, 4)
349+
350+
def test_dfiq_post_approach(self):
351+
dfiq.DFIQScenario(
352+
name="mock_scenario",
353+
dfiq_id="S1003",
354+
dfiq_version="1.0.0",
355+
description="desc",
356+
dfiq_yaml="mock",
357+
).save()
358+
359+
dfiq.DFIQFacet(
360+
name="mock_facet",
361+
dfiq_id="F1005",
362+
dfiq_version="1.0.0",
363+
description="desc",
364+
parent_ids=["S1003"],
365+
dfiq_yaml="mock",
366+
).save()
367+
368+
dfiq.DFIQQuestion(
369+
name="mock_question",
370+
dfiq_id="Q1020",
371+
dfiq_version="1.0.0",
372+
description="desc",
373+
parent_ids=["F1005"],
374+
dfiq_yaml="mock",
375+
).save()
376+
377+
with open("tests/dfiq_test_data/Q1020.10.yaml", "r") as f:
378+
yaml_string = f.read()
379+
380+
response = client.post(
381+
"/api/v2/dfiq/from_yaml",
382+
json={
383+
"dfiq_yaml": yaml_string,
384+
"dfiq_type": dfiq.DFIQType.approach,
385+
"update_indicators": False,
386+
},
387+
)
388+
data = response.json()
389+
self.assertEqual(response.status_code, 200, data)
390+
391+
approach = dfiq.DFIQApproach.get(id=data["id"])
392+
vertices, edges, total = approach.neighbors()
393+
self.assertEqual(len(vertices), 1)
394+
approach.delete()
395+
396+
response = client.post(
397+
"/api/v2/dfiq/from_yaml",
398+
json={
399+
"dfiq_yaml": yaml_string,
400+
"dfiq_type": dfiq.DFIQType.approach,
401+
"update_indicators": True,
402+
},
403+
)
404+
data = response.json()
405+
self.assertEqual(response.status_code, 200, data)
406+
407+
approach = dfiq.DFIQApproach.get(id=data["id"])
408+
vertices, edges, total = approach.neighbors()
409+
self.assertEqual(len(vertices), 4)
410+
279411
def test_wrong_parent(self) -> None:
280412
with open("tests/dfiq_test_data/F1005.yaml", "r") as f:
281413
yaml_string = f.read()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
display_name: Approach1
3+
type: approach
4+
id: Q1020.10
5+
dfiq_version: 1.0.0
6+
tags:
7+
- Lots
8+
- Of
9+
- Tags
10+
description:
11+
summary: Description for approach
12+
details: >
13+
Details for approach
14+
references:
15+
- "ref1"
16+
- "ref2"
17+
references_internal: null
18+
view:
19+
data:
20+
- type: artifact
21+
value: RandomArtifact
22+
- type: description
23+
value: Random description
24+
notes:
25+
covered:
26+
- Covered1
27+
- Covered2
28+
- Covered3
29+
not_covered:
30+
- Not covered1
31+
- Not covered2

0 commit comments

Comments
 (0)