diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml index f6483c39..cab7621d 100755 --- a/spiffworkflow-backend/src/spiffworkflow_backend/api.yml +++ b/spiffworkflow-backend/src/spiffworkflow_backend/api.yml @@ -616,107 +616,18 @@ paths: description: The page number to return. Defaults to page 1. schema: type: integer - - name: start_from - in: query - required: false - description: For filtering - beginning of start window - in seconds since epoch - schema: - type: integer - - name: start_to - in: query - required: false - description: For filtering - end of start window - in seconds since epoch - schema: - type: integer - - name: end_from - in: query - required: false - description: For filtering - beginning of end window - in seconds since epoch - schema: - type: integer - - name: end_to - in: query - required: false - description: For filtering - end of end window - in seconds since epoch - schema: - type: integer - - name: process_status - in: query - required: false - description: For filtering - not_started, user_input_required, waiting, complete, error, or suspended - schema: - type: string - - name: initiated_by_me - in: query - required: false - description: For filtering - show instances initiated by me - schema: - type: boolean - - name: with_tasks_completed_by_me - in: query - required: false - description: For filtering - show instances with tasks completed by me - schema: - type: boolean - - name: with_tasks_completed_by_my_group - in: query - required: false - description: For filtering - show instances with tasks completed by my group - schema: - type: boolean - - name: with_relation_to_me - in: query - required: false - description: For filtering - show instances that have something to do with me - schema: - type: boolean - - name: user_filter - in: query - required: false - description: For filtering - indicates the user has manually entered a query - schema: - type: boolean - - name: report_identifier - in: query - required: false - description: Specifies the identifier of a report to use, if any - schema: - type: string - - name: report_id - in: query - required: false - description: Specifies the identifier of a report to use, if any - schema: - type: integer - - name: user_group_identifier - in: query - required: false - description: The identifier of the group to get the process instances for - schema: - type: string - - name: process_initiator_username - in: query - required: false - description: The username of the process initiator - schema: - type: string - - name: report_columns - in: query - required: false - description: Base64 encoded json of report columns. - schema: - type: string - - name: report_filter_by - in: query - required: false - description: Base64 encoded json of report filter by. - schema: - type: string post: operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_list_for_me summary: Returns a list of process instances that are associated with me. tags: - Process Instances + requestBody: + description: Report dictionary to use. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ProcessInstanceReport" responses: "200": description: Workflow. @@ -747,107 +658,18 @@ paths: description: The page number to return. Defaults to page 1. schema: type: integer - - name: start_from - in: query - required: false - description: For filtering - beginning of start window - in seconds since epoch - schema: - type: integer - - name: start_to - in: query - required: false - description: For filtering - end of start window - in seconds since epoch - schema: - type: integer - - name: end_from - in: query - required: false - description: For filtering - beginning of end window - in seconds since epoch - schema: - type: integer - - name: end_to - in: query - required: false - description: For filtering - end of end window - in seconds since epoch - schema: - type: integer - - name: process_status - in: query - required: false - description: For filtering - not_started, user_input_required, waiting, complete, error, or suspended - schema: - type: string - - name: initiated_by_me - in: query - required: false - description: For filtering - show instances initiated by me - schema: - type: boolean - - name: with_tasks_completed_by_me - in: query - required: false - description: For filtering - show instances with tasks completed by me - schema: - type: boolean - - name: with_tasks_completed_by_my_group - in: query - required: false - description: For filtering - show instances with tasks completed by my group - schema: - type: boolean - - name: with_relation_to_me - in: query - required: false - description: For filtering - show instances that have something to do with me - schema: - type: boolean - - name: user_filter - in: query - required: false - description: For filtering - indicates the user has manually entered a query - schema: - type: boolean - - name: report_identifier - in: query - required: false - description: Specifies the identifier of a report to use, if any - schema: - type: string - - name: report_id - in: query - required: false - description: Specifies the identifier of a report to use, if any - schema: - type: integer - - name: user_group_identifier - in: query - required: false - description: The identifier of the group to get the process instances for - schema: - type: string - - name: process_initiator_username - in: query - required: false - description: The username of the process initiator - schema: - type: string - - name: report_columns - in: query - required: false - description: Base64 encoded json of report columns. - schema: - type: string - - name: report_filter_by - in: query - required: false - description: Base64 encoded json of report filter by. - schema: - type: string post: operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_list summary: Returns a list of process instances. tags: - Process Instances + requestBody: + description: Report dictionary to use. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/ProcessInstanceReport" responses: "200": description: Workflow. @@ -1268,15 +1090,16 @@ paths: summary: Returns all process instance reports for process model tags: - Process Instances + - Process Instances Reports responses: "200": - description: Workflow. + description: Process Instance Report content: application/json: schema: type: array items: - $ref: "#/components/schemas/Workflow" + $ref: "#/components/schemas/ProcessInstanceReport" post: operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_report_create summary: Returns all process instance reports for process model @@ -3098,3 +2921,53 @@ components: description: The timestamp returned in the log type: number example: 123456789.12345 + + ProcessInstanceReport: + properties: + id: + type: number + nullable: true + identifier: + type: string + nullable: true + name: + type: string + nullable: true + report_metadata: + nullable: false + $ref: "#/components/schemas/ReportMetadata" + ReportMetadata: + properties: + columns: + type: array + nullable: false + $ref: "#/components/schemas/ReportMetadataColumn" + filter_by: + type: array + nullable: false + $ref: "#/components/schemas/FilterValue" + order_by: + type: array + nullable: false + ReportMetadataColumn: + properties: + Header: + type: string + nullable: false + accessor: + type: string + nullable: false + fiilterable: + type: boolean + nullable: true + FilterValue: + properties: + field_name: + type: string + nullable: false + field_value: + type: string + nullable: false + fiilterable: + type: string + nullable: false diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance_report.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance_report.py index 74ee1a48..e5b8c5c6 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance_report.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/process_instance_report.py @@ -40,6 +40,13 @@ class ReportMetadata(TypedDict): order_by: list[str] +class Report(TypedDict): + id: int + identifier: str + name: str + report_metadata: ReportMetadata + + class ProcessInstanceReportAlreadyExistsError(Exception): """ProcessInstanceReportAlreadyExistsError.""" @@ -91,8 +98,10 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel): json_data_hash: str = db.Column(db.String(255), nullable=False, index=True) - def get_report_metadata(self) -> dict: - return JsonDataModel.find_data_dict_by_hash(self.json_data_hash) + def get_report_metadata(self) -> ReportMetadata: + rdata_dict = JsonDataModel.find_data_dict_by_hash(self.json_data_hash) + rdata = typing.cast(ReportMetadata, rdata_dict) + return rdata @classmethod def default_order_by(cls) -> list[str]: @@ -106,7 +115,6 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel): user: UserModel, report_metadata: ReportMetadata, ) -> ProcessInstanceReportModel: - """Make_fixture_report.""" process_instance_report = ProcessInstanceReportModel.query.filter_by( identifier=identifier, created_by_id=user.id, @@ -131,25 +139,7 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel): return process_instance_report # type: ignore - @classmethod - def create_with_attributes( - cls, - identifier: str, - report_metadata: ReportMetadata, - user: UserModel, - ) -> ProcessInstanceReportModel: - """Create_with_attributes.""" - process_instance_report = cls( - identifier=identifier, - created_by_id=user.id, - report_metadata=report_metadata, - ) - db.session.add(process_instance_report) - db.session.commit() - return process_instance_report - def with_substitutions(self, field_value: Any, substitution_variables: dict) -> Any: - """With_substitutions.""" if substitution_variables is not None: for key, value in substitution_variables.items(): if isinstance(value, str) or isinstance(value, int): 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 dd249372..ed02134c 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py @@ -3,6 +3,7 @@ import json from typing import Any from typing import Dict from typing import Optional +from typing import Union import flask.wrappers from flask import current_app @@ -35,9 +36,8 @@ from spiffworkflow_backend.models.process_instance_metadata import ( from spiffworkflow_backend.models.process_instance_queue import ( ProcessInstanceQueueModel, ) -from spiffworkflow_backend.models.process_instance_report import ( - ProcessInstanceReportModel, -) +from spiffworkflow_backend.models.process_instance_report import ProcessInstanceReportModel +from spiffworkflow_backend.models.process_instance_report import Report from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.spec_reference import SpecReferenceNotFoundError @@ -231,7 +231,6 @@ def process_instance_list_for_me( page: int = 1, per_page: int = 100, ) -> flask.wrappers.Response: - """Process_instance_list_for_me.""" return process_instance_list( process_model_identifier=process_model_identifier, page=page, @@ -273,7 +272,7 @@ def process_instance_report_show( " report_identifier." ), ) - response_result = {} + response_result: Optional[Union[Report, ProcessInstanceReportModel]] = None if report_hash is not None: json_data = JsonDataModel.query.filter_by(hash=report_hash).first() if json_data is None: @@ -365,7 +364,6 @@ def process_instance_delete( def process_instance_report_list(page: int = 1, per_page: int = 100) -> flask.wrappers.Response: - """Process_instance_report_list.""" process_instance_reports = ProcessInstanceReportModel.query.filter_by( created_by_id=g.user.id, ).all() diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py b/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py index 03620228..d89ed358 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/helpers/base_test.py @@ -19,6 +19,7 @@ from spiffworkflow_backend.models.permission_target import PermissionTargetModel from spiffworkflow_backend.models.process_group import ProcessGroup from spiffworkflow_backend.models.process_group import ProcessGroupSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModel +from spiffworkflow_backend.models.process_instance_report import ReportMetadata from spiffworkflow_backend.models.process_model import NotificationType from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema @@ -379,3 +380,26 @@ class BaseTest: }, ) return process_model + + def post_to_process_instance_list( + self, + client: FlaskClient, + user: UserModel, + report_metadata: Optional[ReportMetadata] = None, + param_string: Optional[str] = "", + ) -> TestResponse: + report_metadata_to_use = report_metadata + if report_metadata_to_use is None: + report_metadata_to_use = self.empty_report_metadata_body() + response = client.post( + f"/v1.0/process-instances{param_string}", + headers=self.logged_in_headers(user), + content_type="application/json", + data=json.dumps({"report_metadata": report_metadata_to_use}), + ) + assert response.status_code == 200 + assert response.json is not None + return response + + def empty_report_metadata_body(self) -> ReportMetadata: + return {"filter_by": [], "columns": [], "order_by": []} diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_debug_controller.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_debug_controller.py index 84fcafb3..d9136020 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_debug_controller.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_debug_controller.py @@ -4,7 +4,6 @@ from tests.spiffworkflow_backend.helpers.base_test import BaseTest class TestDebugController(BaseTest): - def test_test_raise_error( self, app: Flask, diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py index 8fec7d26..20ef475a 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/integration/test_process_api.py @@ -1761,12 +1761,7 @@ class TestProcessApi(BaseTest): headers = self.logged_in_headers(with_super_admin_user) self.create_process_instance_from_process_model_id_with_api(client, process_model_identifier, headers) - response = client.get( - "/v1.0/process-instances", - headers=self.logged_in_headers(with_super_admin_user), - ) - assert response.status_code == 200 - assert response.json is not None + response = self.post_to_process_instance_list(client, with_super_admin_user) assert len(response.json["results"]) == 1 assert response.json["pagination"]["count"] == 1 assert response.json["pagination"]["pages"] == 1 @@ -1807,23 +1802,13 @@ class TestProcessApi(BaseTest): self.create_process_instance_from_process_model_id_with_api(client, process_model_identifier, headers) self.create_process_instance_from_process_model_id_with_api(client, process_model_identifier, headers) - response = client.get( - "/v1.0/process-instances?per_page=2&page=3", - headers=self.logged_in_headers(with_super_admin_user), - ) - assert response.status_code == 200 - assert response.json is not None + response = self.post_to_process_instance_list(client, with_super_admin_user, param_string="?per_page=2&page=3") assert len(response.json["results"]) == 1 assert response.json["pagination"]["count"] == 1 assert response.json["pagination"]["pages"] == 3 assert response.json["pagination"]["total"] == 5 - response = client.get( - "/v1.0/process-instances?per_page=2&page=1", - headers=self.logged_in_headers(with_super_admin_user), - ) - assert response.status_code == 200 - assert response.json is not None + response = self.post_to_process_instance_list(client, with_super_admin_user, param_string="?per_page=2&page=1") assert len(response.json["results"]) == 2 assert response.json["pagination"]["count"] == 2 assert response.json["pagination"]["pages"] == 3 @@ -1867,31 +1852,46 @@ class TestProcessApi(BaseTest): db.session.commit() # Without filtering we should get all 5 instances - response = client.get( - f"/v1.0/process-instances?process_model_identifier={process_model_identifier}", - headers=self.logged_in_headers(with_super_admin_user), + report_metadata_body: ReportMetadata = { + "filter_by": [{"field_name": "process_model_identifier", "field_value": process_model_identifier}], + "columns": [], + "order_by": [], + } + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_metadata_body ) - assert response.json is not None results = response.json["results"] assert len(results) == 5 # filter for each of the status # we should get 1 instance each time for i in range(5): - response = client.get( - f"/v1.0/process-instances?process_status={ProcessInstanceStatus[statuses[i]].value}&process_model_identifier={process_model_identifier}", - headers=self.logged_in_headers(with_super_admin_user), + report_metadata_body = { + "filter_by": [ + {"field_name": "process_model_identifier", "field_value": process_model_identifier}, + {"field_name": "process_status", "field_value": ProcessInstanceStatus[statuses[i]].value}, + ], + "columns": [], + "order_by": [], + } + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_metadata_body ) - assert response.json is not None results = response.json["results"] assert len(results) == 1 assert results[0]["status"] == ProcessInstanceStatus[statuses[i]].value - response = client.get( - f"/v1.0/process-instances?process_status=not_started,complete&process_model_identifier={process_model_identifier}", - headers=self.logged_in_headers(with_super_admin_user), + report_metadata_body = { + "filter_by": [ + {"field_name": "process_model_identifier", "field_value": process_model_identifier}, + {"field_name": "process_status", "field_value": "not_started,complete"}, + ], + "columns": [], + "order_by": [], + } + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_metadata_body ) - assert response.json is not None results = response.json["results"] assert len(results) == 2 assert results[0]["status"] in ["complete", "not_started"] @@ -1899,11 +1899,14 @@ class TestProcessApi(BaseTest): # filter by start/end seconds # start > 1000 - this should eliminate the first - response = client.get( - "/v1.0/process-instances?start_from=1001", - headers=self.logged_in_headers(with_super_admin_user), + report_metadata_body = { + "filter_by": [{"field_name": "start_from", "field_value": 1001}], + "columns": [], + "order_by": [], + } + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_metadata_body ) - assert response.json is not None results = response.json["results"] assert len(results) == 4 for i in range(4): @@ -1915,33 +1918,51 @@ class TestProcessApi(BaseTest): ) # start > 2000, end < 5000 - this should eliminate the first 2 and the last - response = client.get( - "/v1.0/process-instances?start_from=2001&end_to=5999", - headers=self.logged_in_headers(with_super_admin_user), + report_metadata_body = { + "filter_by": [ + {"field_name": "start_from", "field_value": 2001}, + {"field_name": "end_to", "field_value": 5999}, + ], + "columns": [], + "order_by": [], + } + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_metadata_body ) - assert response.json is not None results = response.json["results"] assert len(results) == 2 assert json.loads(results[0]["bpmn_version_control_identifier"]) in (2, 3) assert json.loads(results[1]["bpmn_version_control_identifier"]) in (2, 3) # start > 1000, start < 4000 - this should eliminate the first and the last 2 - response = client.get( - "/v1.0/process-instances?start_from=1001&start_to=3999", - headers=self.logged_in_headers(with_super_admin_user), + report_metadata_body = { + "filter_by": [ + {"field_name": "start_from", "field_value": 1001}, + {"field_name": "start_to", "field_value": 3999}, + ], + "columns": [], + "order_by": [], + } + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_metadata_body ) - assert response.json is not None results = response.json["results"] assert len(results) == 2 assert json.loads(results[0]["bpmn_version_control_identifier"]) in (1, 2) assert json.loads(results[1]["bpmn_version_control_identifier"]) in (1, 2) # end > 2000, end < 6000 - this should eliminate the first and the last - response = client.get( - "/v1.0/process-instances?end_from=2001&end_to=5999", - headers=self.logged_in_headers(with_super_admin_user), + report_metadata_body = { + "filter_by": [ + {"field_name": "end_from", "field_value": 2001}, + {"field_name": "end_to", "field_value": 5999}, + ], + "columns": [], + "order_by": [], + } + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_metadata_body ) - assert response.json is not None results = response.json["results"] assert len(results) == 3 for i in range(3): @@ -1975,7 +1996,7 @@ class TestProcessApi(BaseTest): report_identifier = "testreport" report_metadata: ReportMetadata = {"order_by": ["month"], "filter_by": [], "columns": []} - ProcessInstanceReportModel.create_with_attributes( + ProcessInstanceReportModel.create_report( identifier=report_identifier, report_metadata=report_metadata, user=with_super_admin_user, @@ -1990,129 +2011,6 @@ class TestProcessApi(BaseTest): assert response.json[0]["identifier"] == report_identifier assert response.json[0]["report_metadata"]["order_by"] == ["month"] - # def test_process_instance_report_show_with_default_list( - # self, - # app: Flask, - # client: FlaskClient, - # with_db_and_bpmn_file_cleanup: None, - # with_super_admin_user: UserModel, - # setup_process_instances_for_reports: list[ProcessInstanceModel], - # ) -> None: - # """Test_process_instance_report_show_with_default_list.""" - # process_group_id = "runs_without_input" - # process_model_id = "sample" - # process_model_identifier = f"{process_group_id}/{process_model_id}" - # - # report_metadata = { - # "columns": [ - # {"Header": "id", "accessor": "id"}, - # { - # "Header": "process_model_identifier", - # "accessor": "process_model_identifier", - # }, - # {"Header": "process_group_id", "accessor": "process_group_identifier"}, - # {"Header": "start_in_seconds", "accessor": "start_in_seconds"}, - # {"Header": "status", "accessor": "status"}, - # {"Header": "Name", "accessor": "name"}, - # {"Header": "Status", "accessor": "status"}, - # ], - # "order_by": ["test_score"], - # "filter_by": [ - # {"field_name": "grade_level", "operator": "equals", "field_value": 2} - # ], - # } - # - # report = ProcessInstanceReportModel.create_with_attributes( - # identifier="sure", - # report_metadata=report_metadata, - # user=with_super_admin_user, - # ) - # - # response = client.get( - # f"/v1.0/process-instances/reports/{report.id}", - # headers=self.logged_in_headers(with_super_admin_user), - # ) - # assert response.status_code == 200 - # assert response.json is not None - # assert len(response.json["results"]) == 2 - # assert response.json["pagination"]["count"] == 2 - # assert response.json["pagination"]["pages"] == 1 - # assert response.json["pagination"]["total"] == 2 - # - # process_instance_dict = response.json["results"][0] - # assert type(process_instance_dict["id"]) is int - # assert ( - # process_instance_dict["process_model_identifier"] - # == process_model_identifier - # ) - # assert type(process_instance_dict["start_in_seconds"]) is int - # assert process_instance_dict["start_in_seconds"] > 0 - # assert process_instance_dict["status"] == "complete" - # - # def test_process_instance_report_show_with_dynamic_filter_and_query_param( - # self, - # app: Flask, - # client: FlaskClient, - # with_db_and_bpmn_file_cleanup: None, - # with_super_admin_user: UserModel, - # setup_process_instances_for_reports: list[ProcessInstanceModel], - # ) -> None: - # """Test_process_instance_report_show_with_default_list.""" - # report_metadata = { - # "filter_by": [ - # { - # "field_name": "grade_level", - # "operator": "equals", - # "field_value": "{{grade_level}}", - # } - # ], - # } - # - # report = ProcessInstanceReportModel.create_with_attributes( - # identifier="sure", - # report_metadata=report_metadata, - # user=with_super_admin_user, - # ) - # - # response = client.get( - # f"/v1.0/process-instances/reports/{report.id}?grade_level=1", - # headers=self.logged_in_headers(with_super_admin_user), - # ) - # assert response.status_code == 200 - # assert response.json is not None - # assert len(response.json["results"]) == 1 - - def test_process_instance_report_show_with_bad_identifier( - self, - app: Flask, - client: FlaskClient, - with_db_and_bpmn_file_cleanup: None, - with_super_admin_user: UserModel, - setup_process_instances_for_reports: list[ProcessInstanceModel], - ) -> None: - """Test_process_instance_report_show_with_bad_identifier.""" - response = client.get( - "/v1.0/process-instances/reports/13000000?grade_level=1", - headers=self.logged_in_headers(with_super_admin_user), - ) - assert response.status_code == 404 - data = json.loads(response.get_data(as_text=True)) - assert data["error_code"] == "unknown_process_instance_report" - - def setup_testing_instance( - self, - client: FlaskClient, - process_model_id: str, - with_super_admin_user: UserModel, - ) -> Any: - """Setup_testing_instance.""" - headers = self.logged_in_headers(with_super_admin_user) - response = self.create_process_instance_from_process_model_id_with_api(client, process_model_id, headers) - process_instance = response.json - assert isinstance(process_instance, dict) - process_instance_id = process_instance["id"] - return process_instance_id - def test_error_handler( self, app: Flask, @@ -2134,7 +2032,7 @@ class TestProcessApi(BaseTest): bpmn_file_location=bpmn_file_location, ) - process_instance_id = self.setup_testing_instance(client, process_model_identifier, with_super_admin_user) + process_instance_id = self._setup_testing_instance(client, process_model_identifier, with_super_admin_user) process = db.session.query(ProcessInstanceModel).filter(ProcessInstanceModel.id == process_instance_id).first() assert process is not None @@ -2175,7 +2073,7 @@ class TestProcessApi(BaseTest): bpmn_file_location=bpmn_file_location, ) - process_instance_id = self.setup_testing_instance(client, process_model_identifier, with_super_admin_user) + process_instance_id = self._setup_testing_instance(client, process_model_identifier, with_super_admin_user) process_model = ProcessModelService.get_process_model(process_model_identifier) ProcessModelService.update_process_model( process_model, @@ -2683,8 +2581,9 @@ class TestProcessApi(BaseTest): content_type="application/json", data=json.dumps(data), ) - - print("test_script_unit_test_run") + # TODO: fix this test. I'm not sure it ever worked since it used to NOT check the status code + # and only printed out the test name. + assert response.status_code == 404 def test_send_event( self, @@ -3060,7 +2959,6 @@ class TestProcessApi(BaseTest): with_db_and_bpmn_file_cleanup: None, with_super_admin_user: UserModel, ) -> None: - """Test_can_get_process_instance_list_with_report_metadata.""" process_model = load_test_spec( process_model_id="save_process_instance_metadata/save_process_instance_metadata", bpmn_file_name="save_process_instance_metadata.bpmn", @@ -3087,20 +2985,16 @@ class TestProcessApi(BaseTest): "order_by": ["status"], "filter_by": [], } - process_instance_report = ProcessInstanceReportModel.create_with_attributes( + process_instance_report = ProcessInstanceReportModel.create_report( identifier="sure", report_metadata=report_metadata, user=with_super_admin_user, ) - response = client.get( - f"/v1.0/process-instances?report_identifier={process_instance_report.identifier}", - headers=self.logged_in_headers(with_super_admin_user), + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=process_instance_report.get_report_metadata() ) - assert response.json is not None - assert response.status_code == 200 - assert len(response.json["results"]) == 1 assert response.json["results"][0]["status"] == "complete" assert response.json["results"][0]["id"] == process_instance.id @@ -3160,33 +3054,27 @@ class TestProcessApi(BaseTest): } ], } - process_instance_report_dne = ProcessInstanceReportModel.create_with_attributes( + process_instance_report_dne = ProcessInstanceReportModel.create_report( identifier="dne_report", report_metadata=dne_report_metadata, user=user_one, ) - process_instance_report_user_one = ProcessInstanceReportModel.create_with_attributes( + process_instance_report_user_one = ProcessInstanceReportModel.create_report( identifier="user_one_report", report_metadata=user_one_report_metadata, user=user_one, ) - response = client.get( - f"/v1.0/process-instances?report_identifier={process_instance_report_user_one.identifier}", - headers=self.logged_in_headers(user_one), + response = self.post_to_process_instance_list( + client, user_one, report_metadata=process_instance_report_user_one.get_report_metadata() ) - assert response.json is not None - assert response.status_code == 200 assert len(response.json["results"]) == 2 assert response.json["results"][0]["process_initiator_username"] == user_one.username assert response.json["results"][1]["process_initiator_username"] == user_one.username - response = client.get( - f"/v1.0/process-instances?report_identifier={process_instance_report_dne.identifier}", - headers=self.logged_in_headers(user_one), + response = self.post_to_process_instance_list( + client, user_one, report_metadata=process_instance_report_dne.get_report_metadata() ) - assert response.json is not None - assert response.status_code == 200 assert len(response.json["results"]) == 0 def test_can_get_process_instance_report_column_list( @@ -3196,7 +3084,6 @@ class TestProcessApi(BaseTest): with_db_and_bpmn_file_cleanup: None, with_super_admin_user: UserModel, ) -> None: - """Test_can_get_process_instance_list_with_report_metadata.""" process_model = self.create_process_model_with_metadata() process_instance = self.create_process_instance_from_process_model( process_model=process_model, user=with_super_admin_user @@ -3315,18 +3202,15 @@ class TestProcessApi(BaseTest): "order_by": ["time_ns"], "filter_by": [], } - report_one = ProcessInstanceReportModel.create_with_attributes( + report_one = ProcessInstanceReportModel.create_report( identifier="report_one", report_metadata=report_metadata, user=with_super_admin_user, ) - response = client.get( - f"/v1.0/process-instances?report_id={report_one.id}", - headers=self.logged_in_headers(with_super_admin_user), + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_one.get_report_metadata() ) - assert response.status_code == 200 - assert response.json is not None assert len(response.json["results"]) == 2 assert response.json["results"][0]["id"] == process_instance_one.id assert response.json["results"][1]["id"] == process_instance_two.id @@ -3339,19 +3223,15 @@ class TestProcessApi(BaseTest): "order_by": ["-time_ns"], "filter_by": [], } - report_two = ProcessInstanceReportModel.create_with_attributes( + report_two = ProcessInstanceReportModel.create_report( identifier="report_two", report_metadata=report_metadata, user=with_super_admin_user, ) - response = client.get( - f"/v1.0/process-instances?report_id={report_two.id}", - headers=self.logged_in_headers(with_super_admin_user), + response = self.post_to_process_instance_list( + client, with_super_admin_user, report_metadata=report_two.get_report_metadata() ) - - assert response.status_code == 200 - assert response.json is not None assert len(response.json["results"]) == 2 assert response.json["results"][1]["id"] == process_instance_one.id assert response.json["results"][0]["id"] == process_instance_two.id @@ -3381,3 +3261,16 @@ class TestProcessApi(BaseTest): assert response.status_code == 200 assert response.json is not None assert response.json["process_data_value"] == "hey" + + def _setup_testing_instance( + self, + client: FlaskClient, + process_model_id: str, + with_super_admin_user: UserModel, + ) -> Any: + headers = self.logged_in_headers(with_super_admin_user) + response = self.create_process_instance_from_process_model_id_with_api(client, process_model_id, headers) + process_instance = response.json + assert isinstance(process_instance, dict) + process_instance_id = process_instance["id"] + return process_instance_id diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py index e89a959a..bfda1eb3 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_processor.py @@ -362,9 +362,6 @@ class TestProcessInstanceProcessor(BaseTest): human_task_one = process_instance.active_human_tasks[0] spiff_manual_task = processor.bpmn_process_instance.get_task_from_id(UUID(human_task_one.task_id)) ProcessInstanceService.complete_form_task(processor, spiff_manual_task, {}, initiator_user, human_task_one) - import pdb - - pdb.set_trace() assert ( len(process_instance.active_human_tasks) == 1 ), "expected 1 active human tasks after 2nd one is completed, as we have looped back around." diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_report.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_report.py index 51b3d222..64c7f3f7 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_report.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_process_instance_report.py @@ -125,7 +125,7 @@ # substitution_variables: Optional[dict] = None, # ) -> list[dict]: # """Do_report_with_metadata_and_instances.""" -# process_instance_report = ProcessInstanceReportModel.create_with_attributes( +# process_instance_report = ProcessInstanceReportModel.create_report( # identifier="sure", # report_metadata=report_metadata, # user=BaseTest.find_or_create_user(), diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index 7284eaf6..b3b496d5 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -583,24 +583,24 @@ export default function ProcessInstanceListTable({ }; const removeFieldFromReportMetadata = ( - postBody: ReportMetadata, + reportMetadataToUse: ReportMetadata, fieldName: string ) => { - const filtersToKeep = postBody.filter_by.filter( + const filtersToKeep = reportMetadataToUse.filter_by.filter( (rf: ReportFilter) => rf.field_name !== fieldName ); // eslint-disable-next-line no-param-reassign - postBody.filter_by = filtersToKeep; + reportMetadataToUse.filter_by = filtersToKeep; }; const insertOrUpdateFieldInReportMetadata = ( - postBody: ReportMetadata, + reportMetadataToUse: ReportMetadata, fieldName: string, fieldValue: string ) => { - removeFieldFromReportMetadata(postBody, fieldName); + removeFieldFromReportMetadata(reportMetadataToUse, fieldName); if (fieldValue) { - postBody.filter_by.push({ + reportMetadataToUse.filter_by.push({ field_name: fieldName, field_value: fieldValue, });