Merge branch 'feature/process_api_blueprint_refactor' of github.com:sartography/spiff-arena into feature/process_api_blueprint_refactor

This commit is contained in:
burnettk 2022-12-30 09:31:07 -05:00
commit ba2e77f25f
5 changed files with 67 additions and 119 deletions

View File

@ -1070,7 +1070,7 @@ paths:
schema: schema:
type: integer type: integer
post: post:
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_reset operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_reset
summary: Reset a process instance to an earlier step summary: Reset a process instance to an earlier step
tags: tags:
- Process Instances - Process Instances

View File

@ -26,15 +26,11 @@ from spiffworkflow_backend.models.process_instance import (
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
from spiffworkflow_backend.models.spec_reference import SpecReferenceSchema from spiffworkflow_backend.models.spec_reference import SpecReferenceSchema
from spiffworkflow_backend.models.spiff_step_details import SpiffStepDetailsModel
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.git_service import GitService from spiffworkflow_backend.services.git_service import GitService
from spiffworkflow_backend.services.process_instance_processor import ( from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor, ProcessInstanceProcessor,
) )
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.process_model_service import ProcessModelService
@ -91,46 +87,6 @@ def process_list() -> Any:
return SpecReferenceSchema(many=True).dump(references) return SpecReferenceSchema(many=True).dump(references)
def process_instance_reset(
process_instance_id: int,
modified_process_model_identifier: str,
spiff_step: int = 0,
) -> flask.wrappers.Response:
"""Process_instance_reset."""
process_instance = ProcessInstanceService().get_process_instance(
process_instance_id
)
step_detail = (
db.session.query(SpiffStepDetailsModel)
.filter(
SpiffStepDetailsModel.process_instance_id == process_instance.id,
SpiffStepDetailsModel.spiff_step == spiff_step,
)
.first()
)
if step_detail is not None and process_instance.bpmn_json is not None:
bpmn_json = json.loads(process_instance.bpmn_json)
bpmn_json["tasks"] = step_detail.task_json["tasks"]
bpmn_json["subprocesses"] = step_detail.task_json["subprocesses"]
process_instance.bpmn_json = json.dumps(bpmn_json)
db.session.add(process_instance)
try:
db.session.commit()
except Exception as e:
db.session.rollback()
raise ApiError(
error_code="reset_process_instance_error",
message=f"Could not update the Instance. Original error is {e}",
) from e
return Response(
json.dumps(ProcessInstanceModelSchema().dump(process_instance)),
status=200,
mimetype="application/json",
)
def process_data_show( def process_data_show(
process_instance_id: int, process_instance_id: int,
process_data_identifier: str, process_data_identifier: str,
@ -239,57 +195,6 @@ def _get_required_parameter_or_raise(parameter: str, post_body: dict[str, Any])
return return_value return return_value
def update_task_data(
process_instance_id: str,
modified_process_model_identifier: str,
task_id: str,
body: Dict,
) -> Response:
"""Update task data."""
process_instance = ProcessInstanceModel.query.filter(
ProcessInstanceModel.id == int(process_instance_id)
).first()
if process_instance:
if process_instance.status != "suspended":
raise ProcessInstanceTaskDataCannotBeUpdatedError(
f"The process instance needs to be suspended to udpate the task-data. It is currently: {process_instance.status}"
)
process_instance_bpmn_json_dict = json.loads(process_instance.bpmn_json)
if "new_task_data" in body:
new_task_data_str: str = body["new_task_data"]
new_task_data_dict = json.loads(new_task_data_str)
if task_id in process_instance_bpmn_json_dict["tasks"]:
process_instance_bpmn_json_dict["tasks"][task_id][
"data"
] = new_task_data_dict
process_instance.bpmn_json = json.dumps(process_instance_bpmn_json_dict)
db.session.add(process_instance)
try:
db.session.commit()
except Exception as e:
db.session.rollback()
raise ApiError(
error_code="update_task_data_error",
message=f"Could not update the Instance. Original error is {e}",
) from e
else:
raise ApiError(
error_code="update_task_data_error",
message=f"Could not find Task: {task_id} in Instance: {process_instance_id}.",
)
else:
raise ApiError(
error_code="update_task_data_error",
message=f"Could not update task data for Instance: {process_instance_id}, and Task: {task_id}.",
)
return Response(
json.dumps(ProcessInstanceModelSchema().dump(process_instance)),
status=200,
mimetype="application/json",
)
def send_bpmn_event( def send_bpmn_event(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: str, process_instance_id: str,

View File

@ -560,6 +560,46 @@ def process_instance_task_list(
return make_response(jsonify(tasks), 200) return make_response(jsonify(tasks), 200)
def process_instance_reset(
process_instance_id: int,
modified_process_model_identifier: str,
spiff_step: int = 0,
) -> flask.wrappers.Response:
"""Process_instance_reset."""
process_instance = ProcessInstanceService().get_process_instance(
process_instance_id
)
step_detail = (
db.session.query(SpiffStepDetailsModel)
.filter(
SpiffStepDetailsModel.process_instance_id == process_instance.id,
SpiffStepDetailsModel.spiff_step == spiff_step,
)
.first()
)
if step_detail is not None and process_instance.bpmn_json is not None:
bpmn_json = json.loads(process_instance.bpmn_json)
bpmn_json["tasks"] = step_detail.task_json["tasks"]
bpmn_json["subprocesses"] = step_detail.task_json["subprocesses"]
process_instance.bpmn_json = json.dumps(bpmn_json)
db.session.add(process_instance)
try:
db.session.commit()
except Exception as e:
db.session.rollback()
raise ApiError(
error_code="reset_process_instance_error",
message=f"Could not update the Instance. Original error is {e}",
) from e
return Response(
json.dumps(ProcessInstanceModelSchema().dump(process_instance)),
status=200,
mimetype="application/json",
)
def _get_process_instance( def _get_process_instance(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance: ProcessInstanceModel, process_instance: ProcessInstanceModel,

View File

@ -120,6 +120,6 @@ describe('tasks', () => {
kickOffModelWithForm(); kickOffModelWithForm();
cy.navigateToHome(); cy.navigateToHome();
cy.basicPaginationTest(); cy.basicPaginationTest('process-instance-show-link');
}); });
}); });

View File

@ -116,30 +116,33 @@ Cypress.Commands.add(
} }
); );
Cypress.Commands.add('basicPaginationTest', () => { Cypress.Commands.add(
cy.getBySel('pagination-options').scrollIntoView(); 'basicPaginationTest',
cy.get('.cds--select__item-count').find('.cds--select-input').select('2'); (dataQaTagToUseToEnsureTableHasLoaded = 'paginated-entity-id') => {
cy.getBySel('pagination-options').scrollIntoView();
cy.get('.cds--select__item-count').find('.cds--select-input').select('2');
// NOTE: this is a em dash instead of en dash // NOTE: this is a em dash instead of en dash
cy.contains(/\b12 of \d+/); cy.contains(/\b12 of \d+/);
// ok, trying to ensure that we have everything loaded before we leave this // ok, trying to ensure that we have everything loaded before we leave this
// function and try to sign out. Just showing results 1-2 of blah is not good enough, // function and try to sign out. Just showing results 1-2 of blah is not good enough,
// since the ajax request may not have finished yet. // since the ajax request may not have finished yet.
// to be sure it's finished, grab the log id from page 1. remember it. // to be sure it's finished, grab the log id from page 1. remember it.
// then use the magical contains command that waits for the element to exist AND // then use the magical contains command that waits for the element to exist AND
// for that element to contain the text we're looking for. // for that element to contain the text we're looking for.
cy.getBySel('paginated-entity-id') cy.getBySel(dataQaTagToUseToEnsureTableHasLoaded)
.first() .first()
.then(($element) => { .then(($element) => {
const oldId = $element.text().trim(); const oldId = $element.text().trim();
cy.get('.cds--pagination__button--forward').click(); cy.get('.cds--pagination__button--forward').click();
cy.contains(/\b34 of \d+/); cy.contains(/\b34 of \d+/);
cy.get('.cds--pagination__button--backward').click(); cy.get('.cds--pagination__button--backward').click();
cy.contains(/\b12 of \d+/); cy.contains(/\b12 of \d+/);
cy.contains('[data-qa=paginated-entity-id]', oldId); cy.contains(`[data-qa=${dataQaTagToUseToEnsureTableHasLoaded}]`, oldId);
}); });
}); }
);
Cypress.Commands.add('assertAtLeastOneItemInPaginatedResults', () => { Cypress.Commands.add('assertAtLeastOneItemInPaginatedResults', () => {
cy.contains(/\b[1-9]\d*[1-9]\d* of [1-9]\d*/); cy.contains(/\b[1-9]\d*[1-9]\d* of [1-9]\d*/);