Merge pull request #382 from sartography/feature/381_validate_field_types

fixes #381 Assure that the field type provided is supported.  Catches errors suc…
This commit is contained in:
Dan Funk 2021-09-30 13:46:40 -04:00 committed by GitHub
commit fbfb241c0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 3 deletions

View File

@ -27,8 +27,19 @@ class Task(object):
# Field Types
FIELD_TYPE_FILE = "file"
FIELD_TYPE_STRING = "string"
FIELD_TYPE_LONG = "long"
FIELD_TYPE_BOOLEAN = "boolean"
FIELD_TYPE_DATE = "date"
FIELD_TYPE_ENUM = "enum"
FIELD_TYPE_TEXTAREA = "textarea" # textarea: Multiple lines of text
FIELD_TYPE_AUTO_COMPLETE = "autocomplete"
FIELD_TYPE_FILE = "file"
FIELD_TYPE_FILES = "files" # files: Multiple files
FIELD_TYPE_TEL = "tel" # tel: Phone number
FIELD_TYPE_EMAIL = "email" # email: Email address
FIELD_TYPE_URL = "url" # url: Website address
FIELD_PROP_AUTO_COMPLETE_MAX = "autocomplete_num" # Not used directly, passed in from the front end.
# Required field
@ -77,8 +88,6 @@ class Task(object):
FIELD_PROP_HELP = "help"
##########################################################################
def __init__(self, id, name, title, type, state, lane, form, documentation, data,
@ -103,6 +112,11 @@ class Task(object):
def valid_property_names(cls):
return [value for name, value in vars(cls).items() if name.startswith('FIELD_PROP')]
@classmethod
def valid_field_types(cls):
return [value for name, value in vars(cls).items() if name.startswith('FIELD_TYPE')]
class OptionSchema(ma.Schema):
class Meta:
fields = ["id", "name", "data"]

View File

@ -210,6 +210,7 @@ class WorkflowService(object):
task_name = task.get_name())
# Assure field has valid properties
WorkflowService.check_field_properties(field, task)
WorkflowService.check_field_type(field, task)
# Process the label of the field if it is dynamic.
if field.has_property(Task.FIELD_PROP_LABEL_EXPRESSION):
@ -301,6 +302,14 @@ class WorkflowService(object):
f'The field {field.id} contains an unsupported '
f'property: {name}', task=task)
@staticmethod
def check_field_type(field, task):
"""Assures that the field type is valid."""
valid_types = Task.valid_field_types()
if field.type not in valid_types:
raise ApiError.from_task("invalid_field_type",
f'The field {field.id} has an unknown field type '
f'{field.type}, valid types include {valid_types}', task=task)
@staticmethod
def post_process_form(task):

View File

@ -0,0 +1,43 @@
<?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_08a4c34" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.10.0">
<bpmn:process id="Process_DeleteTaskData" name="Delete Task Data" isExecutable="true">
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>SequenceFlow_12ulmn8</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:endEvent id="Event_19ssfc0">
<bpmn:incoming>SequenceFlow_06786ls</bpmn:incoming>
</bpmn:endEvent>
<bpmn:userTask id="Activity_InvalidField" name="Invalid Custom Field" camunda:formKey="SomeForm">
<bpmn:extensionElements>
<camunda:formData>
<camunda:formField id="TextBadArea" label="Short Description" type="noSuchType" />
</camunda:formData>
</bpmn:extensionElements>
<bpmn:incoming>SequenceFlow_12ulmn8</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_06786ls</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="SequenceFlow_12ulmn8" sourceRef="StartEvent_1" targetRef="Activity_InvalidField" />
<bpmn:sequenceFlow id="SequenceFlow_06786ls" sourceRef="Activity_InvalidField" targetRef="Event_19ssfc0" />
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_DeleteTaskData">
<bpmndi:BPMNEdge id="SequenceFlow_06786ls_di" bpmnElement="SequenceFlow_06786ls">
<di:waypoint x="390" y="120" />
<di:waypoint x="512" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_12ulmn8_di" bpmnElement="SequenceFlow_12ulmn8">
<di:waypoint x="215" y="120" />
<di:waypoint x="290" y="120" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
<dc:Bounds x="179" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Event_19ssfc0_di" bpmnElement="Event_19ssfc0">
<dc:Bounds x="512" y="102" width="36" height="36" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="Activity_1hrox53_di" bpmnElement="Activity_InvalidField">
<dc:Bounds x="290" y="80" width="100" height="80" />
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

View File

@ -148,6 +148,12 @@ class TestWorkflowSpecValidation(BaseTest):
self.assertIn('enum_with_default', final_data)
self.assertEqual('maybe', final_data['enum_with_default']['value'])
def test_invalid_custom_field(self):
self.load_example_data()
errors = self.validate_workflow("invalid_custom_field")
self.assertEqual(1, len(errors))
self.assertEqual("invalid_field_type", errors[0]['code'])
@patch('crc.services.study_service.StudyService._get_study_status')
def test_disabled_spec_validation(self, mock_status):
"""A disabled workflow spec should fail validation"""