Kevin Burnett eae5f7dd2d
the big message improvements branch (#1549)
* imported patch from old message_improvements branch w/ burnettk

* wip.

* merging in changes from message_improvements

* remove patch files that were accidendetally added.

* Added a modal for editing a correlation.  Added ability to delete whole correlation keys.
A little css cleanup.

* * Removing migration - will add back in at the end.
* The Message models API should not require page and per_age parameters, it will return all.
* The Message model list should return a full json description of all messages/correlations for all containing groups.
*

* wip

* Add import, fix class name

* Getting ./bin/pyl to pass

* Getting ./bin/pyl to pass

* Some fe lint fixes

* Some ruff fixes

* Commands to nuke poetry dirs

* Temp skipping of a couple tests

* Getting ./bin/pyl to pass

* This needs to be back in

* Revert back to main

* Factored out data store handling

* Working on factoring out collecting messages, has test failure

* Formatting

* Fixed up test failures

* Remove commentted out lines

* Adding fields

* Fix merge issue

* Re-enable modal

* WIP

* Untested relationships

* Remove correlation key table

* Remove retrieval expression from uniqueness

* Remove commentted out lines

* WIP

* WIP

* WIP

* WIP

* WIP

* Make mypy pass

* Getting formatters to pass

* Add migration

* WIP fixing tests

* WIP fixing tests

* WIP fixing tests

* WIP fixing tests

* WIP fixing tests

* Getting ./bin/pyl to pass

* Fix skipped test

* Fix skipped test

* Getting ./bin/pyl to pass

* Remove unused method

* Remove unused methods

* Clean up unused code

* Refactor to support creating single messages from the UI

* Untested support for processing one process_group

* WIP test

* WIP test

* Filled out test

* Getting ./bin/pyl to pass

* Message Editor Modal Work

* Change migration and add in schemas.

* Swtich to using the associated branch of the process BPMN.io mods

* Get the backend returning messages created from the frontend to the drop down list in the BPMN.io editor.

* Merge main, fix up test

* Getting ./bin/pyl to pass

* Show path in location

* Rename var

* install packages from bpmn-js-spiffworkflow as well for local development

* process group api can add and update message models now w/ burnettk

* backend tests are passing now w/ burnettk

* the launch message edit button is loading the editor w/ burnettk

* updated bpmn-js-spiffworkflow

* pyl is passing w/ burnettk

* updated bpmn-js-spiffworkflow w/ burnettk

* updated bpmn-js-spiffworkflow w/ burnettk

* fixed console errors w/ burnettk

* a couple tweaks w/ burnettk

* save the message json in the new format from the mform w/ burnettk

* display the correlation props in the form w/ burnettk

* default to empty schema so the format is obvious

* allow removing correlation props from web ui w/ burnettk

* added save notification when saving a message on a process model w/ burnettk

* fixed broken test w/ burnettk

* Updating test cases to new message format, tests are failing

* support schema from messages in frontend

* Fixing tests

* Fixing tests

* Fixing tests

* removed references to correlation keys and removed unused components w/ burnettk

* removed temp mesasge model edit button w/ burnettk

* Make mypy pass

* Fixing tests

* Fixing tests

* Getting ./bin/pyl to pass

* save deleted messages before attempting to add new ones w/ burnettk

* set state for the message id so it can be changed w/ burnettk

* do not wait for the message id to be set since it is not necessary w/ burnettk

* updated bpmn-js-spiffworkflow w/ burnettk

* build images for this branch w/ burnettk

* put location in path of message-models so we can control permissions on it w/ burnettk

* fix black

* some coderabbit suggestions

* pull in spiff fix

* Default schema to {}

* Temp fix for invalid schema

* updated bpmn-js-spiffworkflow

* some updates for issue 1626

* minor name tweaks and attempts to update message dropdown in panel when message changes - does not work yet w/ burnettk

* updated bpmn-js-spiffworkflow w/ burnettk

* attempt to call add_message.returned event when message updates w/ burnettk

* treat formData as a state in the MesasgeEditor so it can be updated when the form contents is modified w/ burnettk

* updated bpmn-js-spiffworkflow w/ burnettk

* Feature/merge correlation properties (#1693)

* Merge XML Correlation properties with Process group properties

* updates for messages w/ burnettk

---------

Co-authored-by: theaubmov <ayoubaitlachgar98@gmail.com>
Co-authored-by: jasquat <jasquat@users.noreply.github.com>

* do not wait for message id state to be set to better support new messages w/ burnettk

* updated SpiffWorkflow w/ burnettk

* some cleanup from coderabbit and linting

* added index to message tables, run typecheck in ci, and other updates while code reviewing w/ burnettk

* updated bpmn-js-spiffworkflow w/ burnettk

* remove branch to build

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
Co-authored-by: danfunk <daniel.h.funk@gmail.com>
Co-authored-by: Jon Herron <jon.herron@yahoo.com>
Co-authored-by: burnettk <burnettk@users.noreply.github.com>
Co-authored-by: jasquat <2487833+jasquat@users.noreply.github.com>
Co-authored-by: theaubmov <ayoubaitlachgar98@gmail.com>
2024-06-10 09:15:54 -07:00

188 lines
7.2 KiB
Python

import json
import pytest
from flask import Flask
from flask import g
from flask.testing import FlaskClient
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.message_instance import MessageInstanceModel
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.routes.messages_controller import message_send
from spiffworkflow_backend.services.data_setup_service import DataSetupService
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
class TestMessages(BaseTest):
def test_message_from_api_into_running_process(
self,
app: Flask,
client: FlaskClient,
with_db_and_bpmn_file_cleanup: None,
) -> None:
"""Test sending a message to a running process via the API.
This example workflow will send a message called 'request_approval' and then wait for a response message
of 'approval_result'. This test assures that it will fire the message with the correct correlation properties
and will respond only to a message called 'approval_result' that has the matching correlation properties,
as sent by an API Call.
"""
payload = {
"customer_id": "Sartography",
"po_number": 1001,
"description": "We built a new feature for messages!",
"amount": "100.00",
}
process_instance = self.start_sender_process(client, payload, "test_from_api")
self.assure_a_message_was_sent(process_instance, payload)
self.assure_there_is_a_process_waiting_on_a_message(process_instance)
g.user = process_instance.process_initiator
# Make an API call to the service endpoint, but use the wrong po number
with pytest.raises(ApiError):
message_send("Approval Result", {"payload": {"po_number": 5001}})
# Should return an error when making an API call for right po number, wrong client
with pytest.raises(ApiError):
message_send(
"Approval Result",
{"po_number": 1001, "customer_id": "jon"},
)
# No error when calling with the correct parameters
response = message_send(
"Approval Result",
{"po_number": 1001, "customer_id": "Sartography"},
)
# The response's task data should also match up with the correlation keys.
response_json = response.json
assert response_json["task_data"]["po_number"] == 1001
assert response_json["task_data"]["customer_id"] == "Sartography"
# There is no longer a waiting message
waiting_messages = (
MessageInstanceModel.query.filter_by(message_type="receive")
.filter_by(status="ready")
.filter_by(process_instance_id=process_instance.id)
.all()
)
assert len(waiting_messages) == 0
# The process has completed
assert process_instance.status == "complete"
def test_message_model_list_up_search(
self,
app: Flask,
client: FlaskClient,
with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel,
) -> None:
self.copy_example_process_models()
DataSetupService.save_all_process_models()
response = client.get(
"/v1.0/message-models/examples:1-basic-concepts",
headers=self.logged_in_headers(with_super_admin_user),
content_type="application/json",
)
assert response.status_code == 200
assert response.json is not None
assert len(response.json["messages"]) == 4
response = client.get(
"/v1.0/message-models",
headers=self.logged_in_headers(with_super_admin_user),
content_type="application/json",
)
assert response.status_code == 200
assert response.json is not None
assert len(response.json["messages"]) == 0, "should not have access to messages defined in a sub directory"
def test_process_group_update_syncs_message_models(
self,
app: Flask,
client: FlaskClient,
with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel,
) -> None:
self.create_process_group("bob")
response = client.get(
"/v1.0/message-models/bob",
headers=self.logged_in_headers(with_super_admin_user),
content_type="application/json",
)
assert response.status_code == 200
assert response.json is not None
assert len(response.json["messages"]) == 0
process_group = {
"admin": False,
"description": "Bob's Group",
"display_name": "Bob",
"display_order": 40,
"parent_groups": None,
"messages": {
"table_seated": {
"correlation_properties": {
"table_number": {
"retrieval_expressions": ["table_number"],
},
"franchise_id": {
"retrieval_expressions": ["franchise_id"],
},
},
"schema": {},
},
"order_ready": {
"correlation_properties": {
"table_number": {
"retrieval_expressions": ["table_number"],
},
"franchise_id": {
"retrieval_expressions": ["franchise_id"],
},
},
"schema": {},
},
"end_of_day_receipts": {
"schema": {},
},
},
}
response = client.put(
"/v1.0/process-groups/bob",
headers=self.logged_in_headers(with_super_admin_user),
content_type="application/json",
data=json.dumps(process_group),
)
assert response.status_code == 200
response = client.get(
"/v1.0/message-models/bob",
headers=self.logged_in_headers(with_super_admin_user),
content_type="application/json",
)
assert response.status_code == 200
assert response.json is not None
assert "messages" in response.json
messages = response.json["messages"]
expected_message_identifiers = {"table_seated", "order_ready", "end_of_day_receipts"}
assert len(messages) == len(expected_message_identifiers)
expected_correlation_properties = {
"table_seated": {"table_number": "table_number", "franchise_id": "franchise_id"},
"order_ready": {"table_number": "table_number", "franchise_id": "franchise_id"},
"end_of_day_receipts": {},
}
for message in messages:
assert message["identifier"] in expected_message_identifiers
assert message["location"] == "bob"
assert message["schema"] == {}
cp = {p["identifier"]: p["retrieval_expression"] for p in message["correlation_properties"]}
assert cp == expected_correlation_properties[message["identifier"]]