diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index 65010a01..d26a0abc 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -1070,7 +1070,7 @@ paths: schema: type: integer 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 tags: - Process Instances diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py index 7ad041d2..cff11eb9 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -26,15 +26,11 @@ from spiffworkflow_backend.models.process_instance import ( from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.spec_reference import SpecReferenceCache 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.git_service import GitService from spiffworkflow_backend.services.process_instance_processor import ( ProcessInstanceProcessor, ) -from spiffworkflow_backend.services.process_instance_service import ( - ProcessInstanceService, -) from spiffworkflow_backend.services.process_model_service import ProcessModelService @@ -91,46 +87,6 @@ def process_list() -> Any: 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( process_instance_id: int, process_data_identifier: str, @@ -239,57 +195,6 @@ def _get_required_parameter_or_raise(parameter: str, post_body: dict[str, Any]) 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( modified_process_model_identifier: str, process_instance_id: str, diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py index b93bcecd..08ec712e 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py @@ -560,6 +560,46 @@ def process_instance_task_list( 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( modified_process_model_identifier: str, process_instance: ProcessInstanceModel, diff --git a/spiffworkflow-frontend/cypress/e2e/tasks.cy.js b/spiffworkflow-frontend/cypress/e2e/tasks.cy.js index 73e9ef3b..922c4209 100644 --- a/spiffworkflow-frontend/cypress/e2e/tasks.cy.js +++ b/spiffworkflow-frontend/cypress/e2e/tasks.cy.js @@ -120,6 +120,6 @@ describe('tasks', () => { kickOffModelWithForm(); cy.navigateToHome(); - cy.basicPaginationTest(); + cy.basicPaginationTest('process-instance-show-link'); }); }); diff --git a/spiffworkflow-frontend/cypress/support/commands.js b/spiffworkflow-frontend/cypress/support/commands.js index 624db671..83897860 100644 --- a/spiffworkflow-frontend/cypress/support/commands.js +++ b/spiffworkflow-frontend/cypress/support/commands.js @@ -116,30 +116,33 @@ Cypress.Commands.add( } ); -Cypress.Commands.add('basicPaginationTest', () => { - cy.getBySel('pagination-options').scrollIntoView(); - cy.get('.cds--select__item-count').find('.cds--select-input').select('2'); +Cypress.Commands.add( + 'basicPaginationTest', + (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 - cy.contains(/\b1–2 of \d+/); + // NOTE: this is a em dash instead of en dash + cy.contains(/\b1–2 of \d+/); - // 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, - // since the ajax request may not have finished yet. - // 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 - // for that element to contain the text we're looking for. - cy.getBySel('paginated-entity-id') - .first() - .then(($element) => { - const oldId = $element.text().trim(); - cy.get('.cds--pagination__button--forward').click(); - cy.contains(/\b3–4 of \d+/); - cy.get('.cds--pagination__button--backward').click(); - cy.contains(/\b1–2 of \d+/); - cy.contains('[data-qa=paginated-entity-id]', oldId); - }); -}); + // 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, + // since the ajax request may not have finished yet. + // 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 + // for that element to contain the text we're looking for. + cy.getBySel(dataQaTagToUseToEnsureTableHasLoaded) + .first() + .then(($element) => { + const oldId = $element.text().trim(); + cy.get('.cds--pagination__button--forward').click(); + cy.contains(/\b3–4 of \d+/); + cy.get('.cds--pagination__button--backward').click(); + cy.contains(/\b1–2 of \d+/); + cy.contains(`[data-qa=${dataQaTagToUseToEnsureTableHasLoaded}]`, oldId); + }); + } +); Cypress.Commands.add('assertAtLeastOneItemInPaginatedResults', () => { cy.contains(/\b[1-9]\d*–[1-9]\d* of [1-9]\d*/);