Merge pull request #254 from sartography/bug/225_enum_lookup_same_field_name
Bug/225 enum lookup same field name
This commit is contained in:
commit
7d97fe107d
|
@ -954,7 +954,7 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Workflow"
|
||||
/workflow/{workflow_id}/lookup/{field_id}:
|
||||
/workflow/{workflow_id}/lookup/{task_spec_name}/{field_id}:
|
||||
parameters:
|
||||
- name: workflow_id
|
||||
in: path
|
||||
|
@ -963,6 +963,12 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
- name: task_spec_name
|
||||
in: path
|
||||
required: true
|
||||
description: The name of the current task
|
||||
schema:
|
||||
type: string
|
||||
- name: field_id
|
||||
in: path
|
||||
required: true
|
||||
|
|
|
@ -252,7 +252,7 @@ def delete_workflow_spec_category(cat_id):
|
|||
session.commit()
|
||||
|
||||
|
||||
def lookup(workflow_id, field_id, query=None, value=None, limit=10):
|
||||
def lookup(workflow_id, task_spec_name, field_id, query=None, value=None, limit=10):
|
||||
"""
|
||||
given a field in a task, attempts to find the lookup table or function associated
|
||||
with that field and runs a full-text query against it to locate the values and
|
||||
|
@ -260,7 +260,7 @@ def lookup(workflow_id, field_id, query=None, value=None, limit=10):
|
|||
Tries to be fast, but first runs will be very slow.
|
||||
"""
|
||||
workflow = session.query(WorkflowModel).filter(WorkflowModel.id == workflow_id).first()
|
||||
lookup_data = LookupService.lookup(workflow, field_id, query, value, limit)
|
||||
lookup_data = LookupService.lookup(workflow, task_spec_name, field_id, query, value, limit)
|
||||
return LookupDataSchema(many=True).dump(lookup_data)
|
||||
|
||||
|
||||
|
|
|
@ -148,6 +148,7 @@ class LookupFileModel(db.Model):
|
|||
__tablename__ = 'lookup_file'
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
workflow_spec_id = db.Column(db.String)
|
||||
task_spec_id = db.Column(db.String)
|
||||
field_id = db.Column(db.String)
|
||||
is_ldap = db.Column(db.Boolean) # Allows us to run an ldap query instead of a db lookup.
|
||||
file_data_model_id = db.Column(db.Integer, db.ForeignKey('file_data.id'))
|
||||
|
|
|
@ -40,13 +40,14 @@ class LookupService(object):
|
|||
def get_lookup_model(spiff_task, field):
|
||||
workflow_id = spiff_task.workflow.data[WorkflowProcessor.WORKFLOW_ID_KEY]
|
||||
workflow = db.session.query(WorkflowModel).filter(WorkflowModel.id == workflow_id).first()
|
||||
return LookupService.__get_lookup_model(workflow, field.id)
|
||||
return LookupService.__get_lookup_model(workflow, spiff_task.task_spec.name, field.id)
|
||||
|
||||
@staticmethod
|
||||
def __get_lookup_model(workflow, field_id):
|
||||
def __get_lookup_model(workflow, task_spec_id, field_id):
|
||||
lookup_model = db.session.query(LookupFileModel) \
|
||||
.filter(LookupFileModel.workflow_spec_id == workflow.workflow_spec_id) \
|
||||
.filter(LookupFileModel.field_id == field_id) \
|
||||
.filter(LookupFileModel.task_spec_id == task_spec_id) \
|
||||
.order_by(desc(LookupFileModel.id)).first()
|
||||
|
||||
# one more quick query, to see if the lookup file is still related to this workflow.
|
||||
|
@ -59,14 +60,15 @@ class LookupService(object):
|
|||
|
||||
if not is_current:
|
||||
# Very very very expensive, but we don't know need this till we do.
|
||||
lookup_model = LookupService.create_lookup_model(workflow, field_id)
|
||||
logging.warning("!!!! Making a very expensive call to update the lookup models.")
|
||||
lookup_model = LookupService.create_lookup_model(workflow, task_spec_id, field_id)
|
||||
|
||||
return lookup_model
|
||||
|
||||
@staticmethod
|
||||
def lookup(workflow, field_id, query, value=None, limit=10):
|
||||
def lookup(workflow, task_spec_id, field_id, query, value=None, limit=10):
|
||||
|
||||
lookup_model = LookupService.__get_lookup_model(workflow, field_id)
|
||||
lookup_model = LookupService.__get_lookup_model(workflow, task_spec_id, field_id)
|
||||
|
||||
if lookup_model.is_ldap:
|
||||
return LookupService._run_ldap_query(query, limit)
|
||||
|
@ -74,7 +76,7 @@ class LookupService(object):
|
|||
return LookupService._run_lookup_query(lookup_model, query, value, limit)
|
||||
|
||||
@staticmethod
|
||||
def create_lookup_model(workflow_model, field_id):
|
||||
def create_lookup_model(workflow_model, task_spec_id, field_id):
|
||||
"""
|
||||
This is all really expensive, but should happen just once (per file change).
|
||||
|
||||
|
@ -84,11 +86,12 @@ class LookupService(object):
|
|||
Returns: an array of LookupData, suitable for returning to the API.
|
||||
"""
|
||||
processor = WorkflowProcessor(workflow_model) # VERY expensive, Ludicrous for lookup / type ahead
|
||||
spec, field = processor.find_spec_and_field_by_field_id(field_id)
|
||||
spec, field = processor.find_spec_and_field(task_spec_id, field_id)
|
||||
|
||||
# Clear out all existing lookup models for this workflow and field.
|
||||
existing_models = db.session.query(LookupFileModel) \
|
||||
.filter(LookupFileModel.workflow_spec_id == workflow_model.workflow_spec_id) \
|
||||
.filter(LookupFileModel.task_spec_id == task_spec_id) \
|
||||
.filter(LookupFileModel.field_id == field_id).all()
|
||||
for model in existing_models: # Do it one at a time to cause the required cascade of deletes.
|
||||
db.session.delete(model)
|
||||
|
@ -117,7 +120,7 @@ class LookupService(object):
|
|||
data_model = latest_files[0]
|
||||
|
||||
lookup_model = LookupService.build_lookup_table(data_model, value_column, label_column,
|
||||
workflow_model.workflow_spec_id, field_id)
|
||||
workflow_model.workflow_spec_id, task_spec_id, field_id)
|
||||
|
||||
# Use the results of an LDAP request to populate enum field options
|
||||
elif field.has_property(Task.FIELD_PROP_LDAP_LOOKUP):
|
||||
|
@ -134,7 +137,7 @@ class LookupService(object):
|
|||
return lookup_model
|
||||
|
||||
@staticmethod
|
||||
def build_lookup_table(data_model: FileDataModel, value_column, label_column, workflow_spec_id, field_id):
|
||||
def build_lookup_table(data_model: FileDataModel, value_column, label_column, workflow_spec_id, task_spec_id, field_id):
|
||||
""" In some cases the lookup table can be very large. This method will add all values to the database
|
||||
in a way that can be searched and returned via an api call - rather than sending the full set of
|
||||
options along with the form. It will only open the file and process the options if something has
|
||||
|
@ -153,6 +156,7 @@ class LookupService(object):
|
|||
|
||||
lookup_model = LookupFileModel(workflow_spec_id=workflow_spec_id,
|
||||
field_id=field_id,
|
||||
task_spec_id=task_spec_id,
|
||||
file_data_model_id=data_model.id,
|
||||
is_ldap=False)
|
||||
|
||||
|
|
|
@ -473,11 +473,11 @@ class WorkflowProcessor(object):
|
|||
if nav_item['task_id'] == task.id:
|
||||
return nav_item
|
||||
|
||||
def find_spec_and_field_by_field_id(self, field_id):
|
||||
def find_spec_and_field(self, spec_name, field_id):
|
||||
"""Tracks down a form field by name in the workflow spec,
|
||||
only looks at ready tasks. Returns a tuple of the task, and form"""
|
||||
for spec in self.bpmn_workflow.spec.task_specs.values():
|
||||
if hasattr(spec, "form"):
|
||||
if spec.name == spec_name and hasattr(spec, "form"):
|
||||
for field in spec.form.fields:
|
||||
if field.id == field_id:
|
||||
return spec, field
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: c872232ebdcb
|
||||
Revises: f28ee3722c49
|
||||
Create Date: 2021-03-02 14:35:13.911050
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'c872232ebdcb'
|
||||
down_revision = 'f28ee3722c49'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.execute('delete from lookup_data')
|
||||
op.execute('delete from lookup_file')
|
||||
op.add_column('lookup_file', sa.Column('task_spec_id', sa.String(), nullable=True))
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('lookup_file', 'task_spec_id')
|
||||
# ### end Alembic commands ###
|
|
@ -25,12 +25,6 @@ def upgrade():
|
|||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('approval_file',
|
||||
sa.Column('approval_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column('file_data_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.ForeignKeyConstraint(['approval_id'], ['approval.id'], name='approval_file_approval_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['file_data_id'], ['file_data.id'], name='approval_file_file_data_id_fkey')
|
||||
)
|
||||
op.create_table('approval',
|
||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column('study_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
|
@ -45,4 +39,10 @@ def downgrade():
|
|||
sa.ForeignKeyConstraint(['workflow_id'], ['workflow.id'], name='approval_workflow_id_fkey'),
|
||||
sa.PrimaryKeyConstraint('id', name='approval_pkey')
|
||||
)
|
||||
op.create_table('approval_file',
|
||||
sa.Column('approval_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.Column('file_data_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||
sa.ForeignKeyConstraint(['approval_id'], ['approval.id'], name='approval_file_approval_id_fkey'),
|
||||
sa.ForeignKeyConstraint(['file_data_id'], ['file_data.id'], name='approval_file_file_data_id_fkey')
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,145 @@
|
|||
<?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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_13oadue" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.3">
|
||||
<bpmn:process id="Process_1e56be7" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_07vc55t</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_07vc55t" sourceRef="StartEvent_1" targetRef="Activity_0s5qx04" />
|
||||
<bpmn:exclusiveGateway id="Gateway_1j2ytgn">
|
||||
<bpmn:incoming>Flow_1m73p95</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0gb1k4g</bpmn:outgoing>
|
||||
<bpmn:outgoing>Flow_08kr305</bpmn:outgoing>
|
||||
</bpmn:exclusiveGateway>
|
||||
<bpmn:sequenceFlow id="Flow_0gb1k4g" sourceRef="Gateway_1j2ytgn" targetRef="animals">
|
||||
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">type == 'fruit'</bpmn:conditionExpression>
|
||||
</bpmn:sequenceFlow>
|
||||
<bpmn:sequenceFlow id="Flow_08kr305" sourceRef="Gateway_1j2ytgn" targetRef="fruits">
|
||||
<bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">type=="fruit"</bpmn:conditionExpression>
|
||||
</bpmn:sequenceFlow>
|
||||
<bpmn:exclusiveGateway id="Gateway_14eyj6z">
|
||||
<bpmn:incoming>Flow_09ik0zr</bpmn:incoming>
|
||||
<bpmn:incoming>Flow_1tzwe06</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1ym0gex</bpmn:outgoing>
|
||||
</bpmn:exclusiveGateway>
|
||||
<bpmn:sequenceFlow id="Flow_09ik0zr" sourceRef="animals" targetRef="Gateway_14eyj6z" />
|
||||
<bpmn:sequenceFlow id="Flow_1tzwe06" sourceRef="fruits" targetRef="Gateway_14eyj6z" />
|
||||
<bpmn:endEvent id="Event_0guzzkq">
|
||||
<bpmn:incoming>Flow_1ym0gex</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1ym0gex" sourceRef="Gateway_14eyj6z" targetRef="Event_0guzzkq" />
|
||||
<bpmn:userTask id="animals" name="Animals" camunda:formKey="FormA">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="selectedItem" label="Select An Item" type="enum">
|
||||
<camunda:properties>
|
||||
<camunda:property id="spreadsheet.name" value="animals.xlsx" />
|
||||
<camunda:property id="spreadsheet.value.column" value="Value" />
|
||||
<camunda:property id="spreadsheet.label.column" value="Label" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
</camunda:formData>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_0gb1k4g</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_09ik0zr</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
<bpmn:userTask id="fruits" name="Fruits" camunda:formKey="FromB">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="selectedItem" type="enum">
|
||||
<camunda:properties>
|
||||
<camunda:property id="spreadsheet.name" value="fruits.xlsx" />
|
||||
<camunda:property id="spreadsheet.value.column" value="Value" />
|
||||
<camunda:property id="spreadsheet.label.column" value="Label" />
|
||||
</camunda:properties>
|
||||
</camunda:formField>
|
||||
</camunda:formData>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_08kr305</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1tzwe06</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
<bpmn:sequenceFlow id="Flow_1m73p95" sourceRef="Activity_0s5qx04" targetRef="Gateway_1j2ytgn" />
|
||||
<bpmn:userTask id="Activity_0s5qx04" name="What do you like" camunda:formKey="choose">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="type" type="enum">
|
||||
<camunda:validation>
|
||||
<camunda:constraint name="required" config="True" />
|
||||
</camunda:validation>
|
||||
<camunda:value id="animals" name="Animals" />
|
||||
<camunda:value id="fruits" name="Fruits" />
|
||||
</camunda:formField>
|
||||
</camunda:formData>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_07vc55t</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1m73p95</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
<bpmn:textAnnotation id="TextAnnotation_1vfpzfh">
|
||||
<bpmn:text>Sheet one and sheet two each reference different spread sheets, but they use the same form name.</bpmn:text>
|
||||
</bpmn:textAnnotation>
|
||||
<bpmn:association id="Association_0w3ioqq" sourceRef="animals" targetRef="TextAnnotation_1vfpzfh" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1e56be7">
|
||||
<bpmndi:BPMNShape id="TextAnnotation_1vfpzfh_di" bpmnElement="TextAnnotation_1vfpzfh">
|
||||
<dc:Bounds x="640" y="80" width="200" height="60" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_07vc55t_di" bpmnElement="Flow_07vc55t">
|
||||
<di:waypoint x="188" y="307" />
|
||||
<di:waypoint x="250" y="307" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_0gb1k4g_di" bpmnElement="Flow_0gb1k4g">
|
||||
<di:waypoint x="410" y="282" />
|
||||
<di:waypoint x="410" y="240" />
|
||||
<di:waypoint x="490" y="240" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_08kr305_di" bpmnElement="Flow_08kr305">
|
||||
<di:waypoint x="410" y="332" />
|
||||
<di:waypoint x="410" y="370" />
|
||||
<di:waypoint x="490" y="370" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_09ik0zr_di" bpmnElement="Flow_09ik0zr">
|
||||
<di:waypoint x="590" y="240" />
|
||||
<di:waypoint x="670" y="240" />
|
||||
<di:waypoint x="670" y="282" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1tzwe06_di" bpmnElement="Flow_1tzwe06">
|
||||
<di:waypoint x="590" y="370" />
|
||||
<di:waypoint x="670" y="370" />
|
||||
<di:waypoint x="670" y="332" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1ym0gex_di" bpmnElement="Flow_1ym0gex">
|
||||
<di:waypoint x="695" y="307" />
|
||||
<di:waypoint x="752" y="307" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1m73p95_di" bpmnElement="Flow_1m73p95">
|
||||
<di:waypoint x="350" y="307" />
|
||||
<di:waypoint x="385" y="307" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="Gateway_1j2ytgn_di" bpmnElement="Gateway_1j2ytgn" isMarkerVisible="true">
|
||||
<dc:Bounds x="385" y="282" width="50" height="50" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Gateway_14eyj6z_di" bpmnElement="Gateway_14eyj6z" isMarkerVisible="true">
|
||||
<dc:Bounds x="645" y="282" width="50" height="50" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_0guzzkq_di" bpmnElement="Event_0guzzkq">
|
||||
<dc:Bounds x="752" y="289" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0eua66n_di" bpmnElement="animals">
|
||||
<dc:Bounds x="490" y="200" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0kcbe51_di" bpmnElement="fruits">
|
||||
<dc:Bounds x="490" y="330" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="152" y="289" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_1fixobo_di" bpmnElement="Activity_0s5qx04">
|
||||
<dc:Bounds x="250" y="267" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Association_0w3ioqq_di" bpmnElement="Association_0w3ioqq">
|
||||
<di:waypoint x="589" y="208" />
|
||||
<di:waypoint x="694" y="140" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
Binary file not shown.
|
@ -4,12 +4,12 @@
|
|||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>SequenceFlow_0lvudp8</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_0lvudp8" sourceRef="StartEvent_1" targetRef="Task_14svgcu" />
|
||||
<bpmn:sequenceFlow id="SequenceFlow_0lvudp8" sourceRef="StartEvent_1" targetRef="TaskEnumLookup" />
|
||||
<bpmn:endEvent id="EndEvent_0q4qzl9">
|
||||
<bpmn:incoming>SequenceFlow_02vev7n</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_02vev7n" sourceRef="Task_14svgcu" targetRef="EndEvent_0q4qzl9" />
|
||||
<bpmn:userTask id="Task_14svgcu" name="Enum Lookup Form" camunda:formKey="EnumForm">
|
||||
<bpmn:sequenceFlow id="SequenceFlow_02vev7n" sourceRef="TaskEnumLookup" targetRef="EndEvent_0q4qzl9" />
|
||||
<bpmn:userTask id="TaskEnumLookup" name="Enum Lookup Form" camunda:formKey="EnumForm">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="AllTheNames" label="Select a value" type="enum">
|
||||
|
@ -41,7 +41,7 @@
|
|||
<bpmndi:BPMNShape id="EndEvent_0q4qzl9_di" bpmnElement="EndEvent_0q4qzl9">
|
||||
<dc:Bounds x="432" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="UserTask_18ly1yq_di" bpmnElement="Task_14svgcu">
|
||||
<bpmndi:BPMNShape id="UserTask_18ly1yq_di" bpmnElement="TaskEnumLookup">
|
||||
<dc:Bounds x="270" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>SequenceFlow_0lvudp8</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_0lvudp8" sourceRef="StartEvent_1" targetRef="Task_14svgcu" />
|
||||
<bpmn:sequenceFlow id="SequenceFlow_0lvudp8" sourceRef="StartEvent_1" targetRef="Task_Enum_Lookup" />
|
||||
<bpmn:endEvent id="EndEvent_0q4qzl9">
|
||||
<bpmn:incoming>SequenceFlow_02vev7n</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_02vev7n" sourceRef="Task_14svgcu" targetRef="EndEvent_0q4qzl9" />
|
||||
<bpmn:userTask id="Task_14svgcu" name="Enum Lookup Form" camunda:formKey="EnumForm">
|
||||
<bpmn:sequenceFlow id="SequenceFlow_02vev7n" sourceRef="Task_Enum_Lookup" targetRef="EndEvent_0q4qzl9" />
|
||||
<bpmn:userTask id="Task_Enum_Lookup" name="Enum Lookup Form" camunda:formKey="EnumForm">
|
||||
<bpmn:extensionElements>
|
||||
<camunda:formData>
|
||||
<camunda:formField id="sponsor" label="Select a value" type="autocomplete">
|
||||
|
@ -41,7 +41,7 @@
|
|||
<bpmndi:BPMNShape id="EndEvent_0q4qzl9_di" bpmnElement="EndEvent_0q4qzl9">
|
||||
<dc:Bounds x="432" y="99" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="UserTask_18ly1yq_di" bpmnElement="Task_14svgcu">
|
||||
<bpmndi:BPMNShape id="UserTask_18ly1yq_di" bpmnElement="Task_Enum_Lookup">
|
||||
<dc:Bounds x="270" y="77" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
|
|
|
@ -18,14 +18,14 @@ class TestLookupService(BaseTest):
|
|||
file_model = session.query(FileModel).filter(FileModel.name == "customer_list.xls").first()
|
||||
file_data_model = session.query(FileDataModel).filter(FileDataModel.file_model == file_model).first()
|
||||
with self.assertRaises(ApiError):
|
||||
LookupService.lookup(workflow, "not_the_right_field", "sam", limit=10)
|
||||
LookupService.lookup(workflow, "Task_Enum_Lookup", "not_the_right_field", "sam", limit=10)
|
||||
|
||||
def test_lookup_table_is_not_created_more_than_once(self):
|
||||
spec = BaseTest.load_test_spec('enum_options_with_search')
|
||||
workflow = self.create_workflow('enum_options_with_search')
|
||||
LookupService.lookup(workflow, "sponsor", "sam", limit=10)
|
||||
LookupService.lookup(workflow, "sponsor", "something", limit=10)
|
||||
LookupService.lookup(workflow, "sponsor", "blah", limit=10)
|
||||
LookupService.lookup(workflow, "Task_Enum_Lookup", "sponsor", "sam", limit=10)
|
||||
LookupService.lookup(workflow, "Task_Enum_Lookup", "sponsor", "something", limit=10)
|
||||
LookupService.lookup(workflow, "Task_Enum_Lookup", "sponsor", "blah", limit=10)
|
||||
lookup_records = session.query(LookupFileModel).all()
|
||||
self.assertIsNotNone(lookup_records)
|
||||
self.assertEqual(1, len(lookup_records))
|
||||
|
@ -37,7 +37,7 @@ class TestLookupService(BaseTest):
|
|||
spec = BaseTest.load_test_spec('enum_options_with_search')
|
||||
workflow = self.create_workflow('enum_options_with_search')
|
||||
file_model = session.query(FileModel).filter(FileModel.name == "sponsors.xls").first()
|
||||
LookupService.lookup(workflow, "sponsor", "sam", limit=10)
|
||||
LookupService.lookup(workflow, "Task_Enum_Lookup", "sponsor", "sam", limit=10)
|
||||
lookup_records = session.query(LookupFileModel).all()
|
||||
self.assertIsNotNone(lookup_records)
|
||||
self.assertEqual(1, len(lookup_records))
|
||||
|
@ -58,7 +58,7 @@ class TestLookupService(BaseTest):
|
|||
processor.reset(workflow)
|
||||
workflow = processor.workflow_model
|
||||
|
||||
LookupService.lookup(workflow, "sponsor", "sam", limit=10)
|
||||
LookupService.lookup(workflow, "Task_Enum_Lookup", "sponsor", "sam", limit=10)
|
||||
lookup_records = session.query(LookupFileModel).all()
|
||||
lookup_record = lookup_records[0]
|
||||
lookup_data = session.query(LookupDataModel).filter(LookupDataModel.lookup_file_model == lookup_record).all()
|
||||
|
@ -69,71 +69,103 @@ class TestLookupService(BaseTest):
|
|||
workflow = self.create_workflow('enum_options_from_file')
|
||||
processor = WorkflowProcessor(workflow)
|
||||
processor.do_engine_steps()
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "", value="1000", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "", value="1000", limit=10)
|
||||
self.assertEqual(1, len(results), "It is possible to find an item based on the id, rather than as a search")
|
||||
self.assertIsNotNone(results[0].data)
|
||||
self.assertIsInstance(results[0].data, dict)
|
||||
|
||||
|
||||
def test_lookup_with_two_spreadsheets_with_the_same_field_name_in_different_forms(self):
|
||||
spec = BaseTest.load_test_spec('enum_options_competing_files')
|
||||
workflow = self.create_workflow('enum_options_competing_files')
|
||||
processor = WorkflowProcessor(workflow)
|
||||
|
||||
processor.do_engine_steps()
|
||||
task = processor.get_ready_user_tasks()[0]
|
||||
task.data = {"type": "animal"}
|
||||
processor.complete_task(task)
|
||||
processor.do_engine_steps()
|
||||
task = processor.get_ready_user_tasks()[0]
|
||||
results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="pigs", limit=10)
|
||||
self.assertEqual(1, len(results), "It is possible to find an item based on the id, rather than as a search")
|
||||
self.assertIsNotNone(results[0].data)
|
||||
results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="apples", limit=10)
|
||||
self.assertEqual(0, len(results), "We shouldn't find our fruits mixed in with our animals.")
|
||||
|
||||
|
||||
processor.reset(workflow, clear_data=True)
|
||||
processor.do_engine_steps()
|
||||
task = processor.get_ready_user_tasks()[0]
|
||||
task.data = {"type": "fruit"}
|
||||
processor.complete_task(task)
|
||||
processor.do_engine_steps()
|
||||
task = processor.get_ready_user_tasks()[0]
|
||||
results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="apples", limit=10)
|
||||
self.assertEqual(1, len(results), "It is possible to find an item based on the id, rather than as a search")
|
||||
self.assertIsNotNone(results[0].data)
|
||||
results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="pigs", limit=10)
|
||||
self.assertEqual(0, len(results), "We shouldn't find our animals mixed in with our fruits.")
|
||||
|
||||
|
||||
def test_some_full_text_queries(self):
|
||||
spec = BaseTest.load_test_spec('enum_options_from_file')
|
||||
workflow = self.create_workflow('enum_options_from_file')
|
||||
processor = WorkflowProcessor(workflow)
|
||||
processor.do_engine_steps()
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "", limit=10)
|
||||
self.assertEqual(10, len(results), "Blank queries return everything, to the limit")
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "medicines", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "medicines", limit=10)
|
||||
self.assertEqual(1, len(results), "words in the middle of label are detected.")
|
||||
self.assertEqual("The Medicines Company", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "UVA", limit=10)
|
||||
results = LookupService.lookup(workflow,"TaskEnumLookup", "AllTheNames", "UVA", limit=10)
|
||||
self.assertEqual(1, len(results), "Beginning of label is found.")
|
||||
self.assertEqual("UVA - INTERNAL - GM USE ONLY", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "uva", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup","AllTheNames", "uva", limit=10)
|
||||
self.assertEqual(1, len(results), "case does not matter.")
|
||||
self.assertEqual("UVA - INTERNAL - GM USE ONLY", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "medici", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "medici", limit=10)
|
||||
self.assertEqual(1, len(results), "partial words are picked up.")
|
||||
self.assertEqual("The Medicines Company", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "Genetics Savings", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "Genetics Savings", limit=10)
|
||||
self.assertEqual(1, len(results), "multiple terms are picked up..")
|
||||
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "Genetics Sav", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "Genetics Sav", limit=10)
|
||||
self.assertEqual(1, len(results), "prefix queries still work with partial terms")
|
||||
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "Gen Sav", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "Gen Sav", limit=10)
|
||||
self.assertEqual(1, len(results), "prefix queries still work with ALL the partial terms")
|
||||
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "Inc", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "Inc", limit=10)
|
||||
self.assertEqual(7, len(results), "short terms get multiple correct results.")
|
||||
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "reaction design", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "reaction design", limit=10)
|
||||
self.assertEqual(3, len(results), "all results come back for two terms.")
|
||||
self.assertEqual("Reaction Design", results[0].label, "Exact matches come first.")
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "1 Something", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "1 Something", limit=10)
|
||||
self.assertEqual("1 Something", results[0].label, "Exact matches are preferred")
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "1 (!-Something", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "1 (!-Something", limit=10)
|
||||
self.assertEqual("1 Something", results[0].label, "special characters don't flake out")
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "1 Something", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "1 Something", limit=10)
|
||||
self.assertEqual("1 Something", results[0].label, "double spaces should not be an issue.")
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "in", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "in", limit=10)
|
||||
self.assertEqual(10, len(results), "stop words are not removed.")
|
||||
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
|
||||
|
||||
results = LookupService.lookup(workflow, "AllTheNames", "other", limit=10)
|
||||
results = LookupService.lookup(workflow, "TaskEnumLookup", "AllTheNames", "other", limit=10)
|
||||
self.assertEqual("Other", results[0].label, "Can't find the word 'other', which is an english stop word")
|
||||
|
||||
|
||||
|
|
|
@ -266,8 +266,8 @@ class TestTasksApi(BaseTest):
|
|||
workflow = self.get_workflow_api(workflow)
|
||||
task = workflow.next_task
|
||||
field_id = task.form['fields'][0]['id']
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s?query=%s&limit=5' %
|
||||
(workflow.id, field_id, 'c'), # All records with a word that starts with 'c'
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s/%s?query=%s&limit=5' %
|
||||
(workflow.id, task.name, field_id, 'c'), # All records with a word that starts with 'c'
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json")
|
||||
self.assert_success(rv)
|
||||
|
@ -281,8 +281,8 @@ class TestTasksApi(BaseTest):
|
|||
workflow = self.get_workflow_api(workflow)
|
||||
task = workflow.next_task
|
||||
field_id = task.form['fields'][0]['id']
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s?query=%s&limit=5' %
|
||||
(workflow.id, field_id, 'c'), # All records with a word that starts with 'c'
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s/%s?query=%s&limit=5' %
|
||||
(workflow.id, task.name, field_id, 'c'), # All records with a word that starts with 'c'
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json")
|
||||
self.assert_success(rv)
|
||||
|
@ -290,8 +290,8 @@ class TestTasksApi(BaseTest):
|
|||
self.assertEqual(5, len(results))
|
||||
self.assert_options_populated(results, ['CUSTOMER_NUMBER', 'CUSTOMER_NAME', 'CUSTOMER_CLASS_MEANING'])
|
||||
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s?value=%s' %
|
||||
(workflow.id, field_id, results[0]['value']), # All records with a word that starts with 'c'
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s/%s?value=%s' %
|
||||
(workflow.id, task.name, field_id, results[0]['value']), # All records with a word that starts with 'c'
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json")
|
||||
results = json.loads(rv.get_data(as_text=True))
|
||||
|
@ -311,8 +311,8 @@ class TestTasksApi(BaseTest):
|
|||
task = workflow.next_task
|
||||
field_id = task.form['fields'][0]['id']
|
||||
option_id = task.form['fields'][0]['options'][0]['id']
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s?value=%s' %
|
||||
(workflow.id, field_id, option_id), # All records with a word that starts with 'c'
|
||||
rv = self.app.get('/v1.0/workflow/%i/lookup/%s/%s?value=%s' %
|
||||
(workflow.id, task.name, field_id, option_id), # All records with a word that starts with 'c'
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json")
|
||||
self.assert_success(rv)
|
||||
|
@ -352,8 +352,8 @@ class TestTasksApi(BaseTest):
|
|||
task = workflow.next_task
|
||||
field_id = task.form['fields'][0]['id']
|
||||
# lb3dp is a user record in the mock ldap responses for tests.
|
||||
rv = self.app.get('/v1.0/workflow/%s/lookup/%s?query=%s&limit=5' %
|
||||
(workflow.id, field_id, 'lb3dp'),
|
||||
rv = self.app.get('/v1.0/workflow/%s/lookup/%s/%s?query=%s&limit=5' %
|
||||
(workflow.id, task.name, field_id, 'lb3dp'),
|
||||
headers=self.logged_in_headers(),
|
||||
content_type="application/json")
|
||||
self.assert_success(rv)
|
||||
|
|
Loading…
Reference in New Issue