Merge pull request #432 from sartography/bug/task_data_overwrite_by_previous_submission

assure we don't overwrite task data with a previous form submission i…
This commit is contained in:
Dan Funk 2021-12-08 10:36:27 -05:00 committed by GitHub
commit c3513cc6e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 1 deletions

View File

@ -590,7 +590,9 @@ class WorkflowService(object):
next_task = processor.next_task() next_task = processor.next_task()
if next_task: if next_task:
previous_form_data = WorkflowService.get_previously_submitted_data(processor.workflow_model.id, next_task) previous_form_data = WorkflowService.get_previously_submitted_data(processor.workflow_model.id, next_task)
DeepMerge.merge(next_task.data, previous_form_data) # DeepMerge.merge(next_task.data, previous_form_data)
next_task.data = DeepMerge.merge(previous_form_data, next_task.data)
workflow_api.next_task = WorkflowService.spiff_task_to_api_task(next_task, add_docs_and_forms=True) workflow_api.next_task = WorkflowService.spiff_task_to_api_task(next_task, add_docs_and_forms=True)
# Update the state of the task to locked if the current user does not own the task. # Update the state of the task to locked if the current user does not own the task.
user_uids = WorkflowService.get_users_assigned_to_task(processor, next_task) user_uids = WorkflowService.get_users_assigned_to_task(processor, next_task)

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_6108081" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
<bpmn:process id="Process_6108081" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>Flow_14i1985</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:sequenceFlow id="Flow_14i1985" sourceRef="StartEvent_1" targetRef="pick_letter" />
<bpmn:userTask id="pick_letter" name="Pick Letter" camunda:formKey="Form1">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="template" type="enum">
<camunda:validation>
<camunda:constraint name="required" config="true" />
</camunda:validation>
<camunda:value id="a" name="A is for Apple" />
<camunda:value id="b" name="B is for Boy" />
<camunda:value id="c" name="C is for Cat" />
</camunda:formField>
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>Flow_14i1985</bpmn:incoming>
<bpmn:outgoing>Flow_04lkxb1</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_04lkxb1" sourceRef="pick_letter" targetRef="complete_word" />
<bpmn:endEvent id="Event_1ham0g2">
<bpmn:documentation>the word {{word}} starts with the letter {{letter}}</bpmn:documentation>
<bpmn:incoming>Flow_13ka4e1</bpmn:incoming>
</bpmn:endEvent>
<bpmn:sequenceFlow id="Flow_13ka4e1" sourceRef="complete_word" targetRef="Event_1ham0g2" />
<bpmn:userTask id="complete_word" name="Write a word that starts with letter" camunda:formKey="wordForm">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="template" label="complete the word" type="string" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>Flow_04lkxb1</bpmn:incoming>
<bpmn:outgoing>Flow_13ka4e1</bpmn:outgoing>
</bpmn:userTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_6108081">
<bpmndi:BPMNEdge id="Flow_13ka4e1_di" bpmnElement="Flow_13ka4e1">
<di:waypoint x="630" y="177" />
<di:waypoint x="802" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_04lkxb1_di" bpmnElement="Flow_04lkxb1">
<di:waypoint x="420" y="177" />
<di:waypoint x="530" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_14i1985_di" bpmnElement="Flow_14i1985">
<di:waypoint x="215" y="177" />
<di:waypoint x="320" y="177" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="159" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_0jwhoxz_di" bpmnElement="pick_letter">
<dc:Bounds x="320" y="137" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_1ham0g2_di" bpmnElement="Event_1ham0g2">
<dc:Bounds x="802" y="159" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1ourdhe_di" bpmnElement="complete_word">
<dc:Bounds x="530" y="137" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -0,0 +1,35 @@
import json
from tests.base_test import BaseTest
class TestFormFieldName(BaseTest):
def test_prefer_task_data_over_previous_form_submission(self):
"""It is nice to have the previous information show up when having to re-complete a form you filled
out previously. However, you don't want to overwrite something if it exists in the task-data already.
You can demonstrate this by setting the same value with two different forms. The second of the two
forms should always start with the data submitted by the first form. No mater how many times we submit and
go back. """
workflow = self.create_workflow('prefer_task_data_over_previous_form_submission')
workflow_api = self.get_workflow_api(workflow)
task_1 = workflow_api.next_task
self.assertEquals('pick_letter', task_1.name)
workflow_api = self.complete_form(workflow, task_1, {'template':'a'})
task_2 = workflow_api.next_task
self.assertEquals('complete_word', task_2.name)
self.assertEquals('a', task_2.data['template'])
workflow_api = self.complete_form(workflow, task_2, {'template':'a'})
self.restart_workflow_api(workflow_api, clear_data=False)
workflow_api = self.get_workflow_api(workflow)
task_1 = workflow_api.next_task
self.assertEquals('pick_letter', task_1.name)
workflow_api = self.complete_form(workflow, task_1, {'template':'b'})
task_2 = workflow_api.next_task
self.assertEquals('complete_word', task_2.name)
# HERE is the real test, if we use the task data, then template is set to "b", but if we
# overwrite the task_data with the last form submission, it ends up being "a". If
# the value is already set in task_data, it should not be overwitten.
self.assertEquals('b', task_2.data['template'])