From 386fb21e2e8b9446b1f2fd21ba7798f1fd001357 Mon Sep 17 00:00:00 2001 From: spokenbird Date: Wed, 11 Oct 2023 14:12:01 -0700 Subject: [PATCH] Do not map incomplete iterations in subflows during PDF generation [#185984169] Co-authored-by: Chibuisi Enyia --- .../library/pdf/SubflowFieldPreparer.java | 17 +-- .../controllers/PdfControllerTest.java | 4 +- .../pdf/SubflowFieldPreparersTest.java | 102 +++++++++++++++--- 3 files changed, 101 insertions(+), 22 deletions(-) diff --git a/src/main/java/formflow/library/pdf/SubflowFieldPreparer.java b/src/main/java/formflow/library/pdf/SubflowFieldPreparer.java index f7619d9c5..039eda02b 100644 --- a/src/main/java/formflow/library/pdf/SubflowFieldPreparer.java +++ b/src/main/java/formflow/library/pdf/SubflowFieldPreparer.java @@ -82,6 +82,7 @@ public Map prepareSubmissionFields(Submission submissio Map preppedFields = new HashMap<>(); List> subflowDataList = new ArrayList<>(); Map subflowMap = pdfMap.getSubflowInfo(); + final List IGNORED_FIELDS = List.of("uuid", "iterationIsComplete"); if (subflowMap == null) { return Collections.emptyMap(); @@ -92,7 +93,7 @@ public Map prepareSubmissionFields(Submission submissio subflowDataList.addAll((List>) submission.getInputData().get(pdfSubflowName)); } - if (subflowDataList.size() > 0) { + if (!subflowDataList.isEmpty()) { AtomicInteger atomInteger = new AtomicInteger(1); subflowDataList.forEach(iteration -> { @@ -101,12 +102,16 @@ public Map prepareSubmissionFields(Submission submissio if (atomInteger.get() > pdfSubflow.getTotalIterations()) { return; } - - // remove unnecessary fields - iteration.remove("uuid"); - iteration.remove("iterationIsComplete"); + + if (iteration.get("iterationIsComplete") != null && iteration.get("iterationIsComplete").equals(false)) { + return; + } + iteration.forEach((key, value) -> { - + if (IGNORED_FIELDS.contains(key)) { + return; + } + String newKey = getNewKey(key, atomInteger.get()); if (!pdfMap.getAllFields().containsKey(newKey.replace("[]", ""))) { diff --git a/src/test/java/formflow/library/controllers/PdfControllerTest.java b/src/test/java/formflow/library/controllers/PdfControllerTest.java index 6366f8079..a4063360d 100644 --- a/src/test/java/formflow/library/controllers/PdfControllerTest.java +++ b/src/test/java/formflow/library/controllers/PdfControllerTest.java @@ -64,7 +64,7 @@ void shouldReturn404WhenFlowDoesNotExist() throws Exception { } @Test - public void getDownloadGeneratesAndReturnsFilledFlattenedPdf() throws Exception { + void getDownloadGeneratesAndReturnsFilledFlattenedPdf() throws Exception { session.setAttribute("id", submission.getId()); MvcResult result = mockMvc.perform(get("/download/ubi/" + submission.getId()).session(session)) .andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION, @@ -77,7 +77,7 @@ public void getDownloadGeneratesAndReturnsFilledFlattenedPdf() throws Exception } @Test - public void shouldNotAllowDownloadingAPdfWithADifferentSubmissionIdThanTheActiveSession() throws Exception { + void shouldNotAllowDownloadingAPdfWithADifferentSubmissionIdThanTheActiveSession() throws Exception { session.setAttribute("id", UUID.randomUUID()); mockMvc.perform(get("/download/ubi/" + submission.getId()).session(session)) diff --git a/src/test/java/formflow/library/pdf/SubflowFieldPreparersTest.java b/src/test/java/formflow/library/pdf/SubflowFieldPreparersTest.java index 220ba16eb..da733c7fa 100644 --- a/src/test/java/formflow/library/pdf/SubflowFieldPreparersTest.java +++ b/src/test/java/formflow/library/pdf/SubflowFieldPreparersTest.java @@ -50,42 +50,42 @@ void shouldNotMapIterationsInASubflowGreaterThanMaxIterations() { iteration1.put("foo", "the foo 1"); iteration1.put("bar", "the bar 1"); iteration1.put("uuid", "uuid1"); - iteration1.put("iterationIsComplete", "true"); + iteration1.put("iterationIsComplete", true); Map iteration2 = new HashMap<>(); iteration2.put("foo", "the foo 2"); iteration2.put("bar", "the bar 2"); iteration2.put("uuid", "uuid2"); - iteration2.put("iterationIsComplete", "true"); + iteration2.put("iterationIsComplete", true); Map iteration3 = new HashMap<>(); iteration3.put("foo", "the foo 3"); iteration3.put("bar", "the bar 3"); iteration3.put("uuid", "uuid3"); - iteration3.put("iterationIsComplete", "true"); + iteration3.put("iterationIsComplete", true); Map iteration4 = new HashMap<>(); iteration4.put("foo", "the foo 4"); iteration4.put("bar", "the bar 4"); iteration4.put("uuid", "uuid4"); - iteration4.put("iterationIsComplete", "true"); + iteration4.put("iterationIsComplete", true); Map iteration5 = new HashMap<>(); iteration5.put("foo", "the foo 5"); iteration5.put("bar", "the bar 5"); iteration5.put("uuid", "uuid5"); - iteration5.put("iterationIsComplete", "true"); + iteration5.put("iterationIsComplete", true); Map iteration6 = new HashMap<>(); iteration6.put("foo", "the foo 6"); iteration6.put("bar", "the bar 6"); iteration6.put("uuid", "uuid6"); - iteration6.put("iterationIsComplete", "true"); + iteration6.put("iterationIsComplete", true); Map iteration7 = new HashMap<>(); iteration7.put("foo", "the foo 7"); iteration7.put("bar", "the bar 7"); iteration7.put("uuid", "uuid7"); - iteration7.put("iterationIsComplete", "true"); + iteration7.put("iterationIsComplete", true); Map iteration8 = new HashMap<>(); iteration8.put("foo", "the foo 8"); iteration8.put("bar", "the bar 8"); iteration8.put("uuid", "uuid8"); - iteration8.put("iterationIsComplete", "true"); + iteration8.put("iterationIsComplete", true); submission = Submission.builder().flow("flow1") .inputData( Map.of( @@ -130,17 +130,17 @@ void submissionWithLessIterationsThanMaxIterationsShouldOnlyMapExistingIteration iteration1.put("foo", "the foo 1"); iteration1.put("bar", "the bar 1"); iteration1.put("uuid", "uuid1"); - iteration1.put("iterationIsComplete", "true"); + iteration1.put("iterationIsComplete", true); Map iteration2 = new HashMap<>(); iteration2.put("foo", "the foo 2"); iteration2.put("bar", "the bar 2"); iteration2.put("uuid", "uuid2"); - iteration2.put("iterationIsComplete", "true"); + iteration2.put("iterationIsComplete", true); Map iteration3 = new HashMap<>(); iteration3.put("foo", "the foo 3"); iteration3.put("bar", "the bar 3"); iteration3.put("uuid", "uuid3"); - iteration3.put("iterationIsComplete", "true"); + iteration3.put("iterationIsComplete", true); submission = Submission.builder().flow("flow1") .inputData( @@ -177,13 +177,13 @@ void shouldAddCorrectSuffixForCheckboxFieldsInSubflows() { iteration1.put("bar", "the bar 1"); iteration1.put("checkboxInput[]", List.of("item1", "item2", "item3")); iteration1.put("uuid", "uuid1"); - iteration1.put("iterationIsComplete", "true"); + iteration1.put("iterationIsComplete", true); Map iteration2 = new HashMap<>(); iteration2.put("foo", "the foo 2"); iteration2.put("bar", "the bar 2"); iteration2.put("checkboxInput[]", List.of("item1", "item2", "item3")); iteration2.put("uuid", "uuid2"); - iteration2.put("iterationIsComplete", "true"); + iteration2.put("iterationIsComplete", true); submission = Submission.builder().flow("flow1") .inputData( @@ -223,7 +223,6 @@ void shouldNotThrownWhenNoSubflow() { ) ); pdfMapWithoutSubflow.setFlow("flow1"); - PdfMapSubflow noSubflow = new PdfMapSubflow(); pdfMapConfiguration = new PdfMapConfiguration(List.of(pdfMapWithoutSubflow)); SubflowFieldPreparer noSubflowFieldPreparer = new SubflowFieldPreparer(); @@ -242,4 +241,79 @@ void shouldNotThrownWhenNoSubflow() { pdfMapConfiguration.getPdfMap("flow1")) ).doesNotThrowAnyException(); } + + @Test + void shouldNotCreateFieldsForIncompleteSubflowIterations() { + Map iteration1 = new HashMap<>(); + iteration1.put("foo", "foo from first iteration will not be removed because iteration is complete"); + iteration1.put("bar", "bar from first iteration will not be removed because iteration is complete"); + iteration1.put("uuid", "uuid1"); + iteration1.put("iterationIsComplete", true); + Map iteration2 = new HashMap<>(); + iteration2.put("foo", "foo from second iteration will be removed because iteration is not complete"); + iteration2.put("bar", "bar from second iteration will be removed because iteration is not complete"); + iteration2.put("uuid", "uuid2"); + iteration2.put("iterationIsComplete", false); + Map iteration3 = new HashMap<>(); + iteration3.put("foo", "foo from third iteration will not be removed because iteration is complete"); + iteration3.put("bar", "bar from third iteration will not be removed because iteration is complete"); + iteration3.put("uuid", "uuid3"); + iteration3.put("iterationIsComplete", true); + + submission = Submission.builder().flow("flow1") + .inputData( + Map.of("testSubflow", List.of( + iteration1, + iteration2, + iteration3) + )).build(); + + Map resultMap = subflowFieldPreparer.prepareSubmissionFields(submission, + pdfMapConfiguration.getPdfMap("flow1")); + + assertThat(resultMap.equals( + Map.of( + "foo_1", new SingleField("foo", "foo from first iteration will not be removed because iteration is complete", 1), + "bar_1", new SingleField("bar", "bar from first iteration will not be removed because iteration is complete", 1), + "foo_2", new SingleField("foo", "foo from third iteration will not be removed because iteration is complete", 2), + "bar_2", new SingleField("bar", "bar from third iteration will not be removed because iteration is complete", 2) + ) + )).isTrue(); + } + + @Test + void shouldNotPrepareIgnoredSubflowFields() { + Map iteration1 = new HashMap<>(); + iteration1.put("foo", "foo 1"); + iteration1.put("bar", "bar 1"); + iteration1.put("uuid", "uuid1"); + iteration1.put("iterationIsComplete", true); + Map iteration2 = new HashMap<>(); + iteration2.put("foo", "foo 2"); + iteration2.put("bar", "bar 2"); + iteration2.put("uuid", "uuid2"); + iteration2.put("iterationIsComplete", true); + + + submission = Submission.builder().flow("flow1") + .inputData( + Map.of("testSubflow", List.of( + iteration1, + iteration2) + )).build(); + + Map resultMap = subflowFieldPreparer.prepareSubmissionFields(submission, + pdfMapConfiguration.getPdfMap("flow1")); + + + // Result does not include UUID or iterationIsComplete which should be ignored + assertThat(resultMap.equals( + Map.of( + "foo_1", new SingleField("foo", "foo 1", 1), + "bar_1", new SingleField("bar", "bar 1", 1), + "foo_2", new SingleField("foo", "foo 2", 2), + "bar_2", new SingleField("bar", "bar 2", 2) + ) + )).isTrue(); + } }