Validation was failing for enum_label() expressions when called within a sub-process. Possible (but unlikely) that this would occur outside validation.

This commit is contained in:
Dan 2021-11-09 12:55:06 -05:00
parent 9376d3deaf
commit d1eae3c15a
5 changed files with 39 additions and 14 deletions

View File

@ -7,6 +7,7 @@ import sentry_sdk
import connexion
from SpiffWorkflow import WorkflowException
from SpiffWorkflow.exceptions import WorkflowTaskExecException
from connexion import ProblemException
from flask import Response
from flask_cors import CORS
@ -139,8 +140,8 @@ def sync_with_testing():
@app.cli.command()
@click.argument("study_id")
@click.argument("category")
@click.argument("spec_id")
@click.argument("category", required=False)
@click.argument("spec_id", required=False)
def validate_all(study_id, category=None, spec_id=None):
"""Step through all the local workflows and validate them, returning any errors. This make take forever.
Please provide a real study id to use for validation, an optional category can be specified to only validate
@ -148,7 +149,13 @@ def validate_all(study_id, category=None, spec_id=None):
from crc.models.workflow import WorkflowSpecModel
from crc.services.workflow_service import WorkflowService
from crc.api.common import ApiError
from crc.models.study import StudyModel
from crc.models.user import UserModel
from flask import g
study = session.query(StudyModel).filter(StudyModel.id == study_id).first()
g.user = session.query(UserModel).filter(UserModel.uid == study.user_uid).first()
g.token = "anything_is_fine_just_need_something."
specs = session.query(WorkflowSpecModel).all()
for spec in specs:
if spec_id and spec_id != spec.id:
@ -158,10 +165,15 @@ def validate_all(study_id, category=None, spec_id=None):
try:
WorkflowService.test_spec(spec.id, validate_study_id=study_id)
except ApiError as e:
print("Failed to validate workflow " + spec.id)
print(e)
return
except WorkflowException as e:
print("Failed to validate workflow " + spec.id)
if e.code == 'disabled_workflow':
print(f"Skipping {spec.id} in category {spec.category.display_name}, it is disabled for this study.")
else:
print(f"API Error {e.code}, validate workflow {spec.id} in Category {spec.category.display_name}")
return
except WorkflowTaskExecException as e:
print(f"Workflow Error, {e}, in Task {e.task.name} validate workflow {spec.id} in Category {spec.category.display_name}")
return
except Exception as e:
print(f"Unexpected Error, {e} validate workflow {spec.id} in Category {spec.category.display_name}")
print(e)
return

View File

@ -32,9 +32,7 @@ pet_label = enum_label(task='task_pet_form',field='pet',value='1') // might r
# get the field information for the provided task_name (NOT the current task)
workflow_model = db.session.query(WorkflowModel).filter(WorkflowModel.id == workflow_id).first()
processor = WorkflowProcessor(workflow_model)
spec, field = processor.find_spec_and_field(task_name, field_name)
print(spec)
field = self.find_field(task_name, field_name, spiff_task.workflow)
print(field)
if field.type == Task.FIELD_TYPE_AUTO_COMPLETE:
@ -44,6 +42,18 @@ pet_label = enum_label(task='task_pet_form',field='pet',value='1') // might r
elif field.has_property(Task.FIELD_PROP_DATA_NAME):
return self.enum_from_task_data_label(spiff_task, field, value)
def find_field(self, task_name, field_name, workflow):
for spec in workflow.spec.task_specs.values():
if spec.name == task_name:
for field in spec.form.fields:
if field.id == field_name:
return field
raise ApiError("invalid_field",
f"The task '{task_name}' has no field named '{field_name}'")
raise ApiError("invalid_spec",
f"Unable to find a task in the workflow called '{task_name}'")
def autocomplete_label(self, workflow_model, task_name, field, value):
label_column = field.get_property(Task.FIELD_PROP_LABEL_COLUMN)
result = LookupService().lookup(workflow_model, task_name, field.id, '', value=value, limit=1)

View File

@ -199,7 +199,7 @@ class LookupService(object):
def _run_lookup_query(lookup_file_model, query, value, limit):
db_query = LookupDataModel.query.filter(LookupDataModel.lookup_file_model == lookup_file_model)
if value is not None: # Then just find the model with that value
db_query = db_query.filter(LookupDataModel.value == value)
db_query = db_query.filter(LookupDataModel.value == str(value))
else:
# Build a full text query that takes all the terms provided and executes each term as a prefix query, and
# OR's those queries together. The order of the results is handled as a standard "Like" on the original

View File

@ -433,7 +433,7 @@ class WorkflowService(object):
elif lookup_model:
data = db.session.query(LookupDataModel).\
filter(LookupDataModel.lookup_file_model == lookup_model). \
filter(LookupDataModel.value == default).\
filter(LookupDataModel.value == str(default)).\
first()
if not data:
raise ApiError.from_task("invalid_default", "You specified a default value that does not exist in "

View File

@ -2,6 +2,7 @@ from tests.base_test import BaseTest
from crc.scripts.enum_label import EnumLabel
from crc.api.common import ApiError
from crc.services.workflow_processor import WorkflowProcessor
class TestGetEnumLabel(BaseTest):
@ -12,8 +13,10 @@ class TestGetEnumLabel(BaseTest):
self.workflow_api = self.get_workflow_api(self.workflow)
# Assure the form has been loaded at least once.
self.task = self.workflow_api.next_task
self.assertEqual(self.task.name, 'myFormTask')
processor = WorkflowProcessor(self.workflow)
processor.do_engine_steps()
self.task = processor.next_task()
self.assertEqual(self.task.get_name(), 'myFormTask')
self.labelScript = EnumLabel()