Merge remote-tracking branch 'origin/main' into bug/improve_reset_to_previous_task
This commit is contained in:
commit
e417eb57f3
File diff suppressed because it is too large
Load Diff
|
@ -3121,7 +3121,7 @@ lxml = "*"
|
||||||
type = "git"
|
type = "git"
|
||||||
url = "https://github.com/sartography/SpiffWorkflow"
|
url = "https://github.com/sartography/SpiffWorkflow"
|
||||||
reference = "main"
|
reference = "main"
|
||||||
resolved_reference = "0a455cdd221137ec52d39801dd5ad6dabad4ed4f"
|
resolved_reference = "a844b34f9327a572d8f26110a01af21e22c548d1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlalchemy"
|
name = "sqlalchemy"
|
||||||
|
|
|
@ -1786,6 +1786,18 @@ class ProcessInstanceProcessor:
|
||||||
)
|
)
|
||||||
task_service.update_all_tasks_from_spiff_tasks(spiff_tasks, deleted_tasks, start_time)
|
task_service.update_all_tasks_from_spiff_tasks(spiff_tasks, deleted_tasks, start_time)
|
||||||
|
|
||||||
|
# we may want to move this to task_service.update_all_tasks_from_spiff_tasks but not sure it's always good to it.
|
||||||
|
# for cancelled tasks, spiff only returns tasks that were cancelled, not the ones that were deleted so we have to find them
|
||||||
|
spiff_task_guids = [str(st.id) for st in spiff_tasks]
|
||||||
|
tasks_no_longer_in_spiff = TaskModel.query.filter(
|
||||||
|
and_(
|
||||||
|
TaskModel.process_instance_id == self.process_instance_model.id,
|
||||||
|
TaskModel.guid.not_in(spiff_task_guids), # type: ignore
|
||||||
|
)
|
||||||
|
).all()
|
||||||
|
for task in tasks_no_longer_in_spiff:
|
||||||
|
db.session.delete(task)
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
self.process_instance_model.status = "terminated"
|
self.process_instance_model.status = "terminated"
|
||||||
db.session.add(self.process_instance_model)
|
db.session.add(self.process_instance_model)
|
||||||
|
|
|
@ -462,7 +462,10 @@ class TaskService:
|
||||||
human_tasks_to_clear = HumanTaskModel.query.filter(
|
human_tasks_to_clear = HumanTaskModel.query.filter(
|
||||||
HumanTaskModel.task_id.in_(deleted_task_ids) # type: ignore
|
HumanTaskModel.task_id.in_(deleted_task_ids) # type: ignore
|
||||||
).all()
|
).all()
|
||||||
for task in tasks_to_clear + human_tasks_to_clear:
|
|
||||||
|
# delete human tasks first to avoid potential conflicts when deleting tasks.
|
||||||
|
# otherwise sqlalchemy returns several warnings.
|
||||||
|
for task in human_tasks_to_clear + tasks_to_clear:
|
||||||
db.session.delete(task)
|
db.session.delete(task)
|
||||||
|
|
||||||
# Note: Can't restrict this to definite, because some things are updated and are now CANCELLED
|
# Note: Can't restrict this to definite, because some things are updated and are now CANCELLED
|
||||||
|
@ -473,6 +476,7 @@ class TaskService:
|
||||||
spiff_tasks_updated[str(spiff_task.id)] = spiff_task
|
spiff_tasks_updated[str(spiff_task.id)] = spiff_task
|
||||||
for _id, spiff_task in spiff_tasks_updated.items():
|
for _id, spiff_task in spiff_tasks_updated.items():
|
||||||
self.update_task_model_with_spiff_task(spiff_task)
|
self.update_task_model_with_spiff_task(spiff_task)
|
||||||
|
|
||||||
self.save_objects_to_database()
|
self.save_objects_to_database()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -1611,6 +1611,10 @@ class TestProcessApi(BaseTest):
|
||||||
assert len(ready_tasks) == 1
|
assert len(ready_tasks) == 1
|
||||||
ready_task = ready_tasks[0]
|
ready_task = ready_tasks[0]
|
||||||
|
|
||||||
|
# check all_tasks here to ensure we actually deleted items when cancelling the instance
|
||||||
|
all_tasks = TaskModel.query.filter_by(process_instance_id=process_instance_id).all()
|
||||||
|
assert len(all_tasks) == 8
|
||||||
|
|
||||||
response = client.post(
|
response = client.post(
|
||||||
f"/v1.0/process-instance-terminate/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}",
|
f"/v1.0/process-instance-terminate/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}",
|
||||||
headers=self.logged_in_headers(with_super_admin_user),
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
|
@ -1621,11 +1625,13 @@ class TestProcessApi(BaseTest):
|
||||||
process_instance = ProcessInstanceModel.query.filter_by(id=process_instance_id).first()
|
process_instance = ProcessInstanceModel.query.filter_by(id=process_instance_id).first()
|
||||||
assert process_instance
|
assert process_instance
|
||||||
assert process_instance.status == "terminated"
|
assert process_instance.status == "terminated"
|
||||||
assert ready_task.state == "CANCELLED"
|
|
||||||
|
|
||||||
# TODO: uncomment this once spiff is returning deleted tasks on cancel
|
ready_task_that_is_now_cancelled = TaskModel.query.filter_by(guid=ready_task.guid).first()
|
||||||
# remaining_tasks = TaskModel.query.filter_by(process_instance_id=process_instance_id).all()
|
assert ready_task_that_is_now_cancelled is not None
|
||||||
# assert len(remaining_tasks) == 3
|
assert ready_task_that_is_now_cancelled.state == "CANCELLED"
|
||||||
|
|
||||||
|
remaining_tasks = TaskModel.query.filter_by(process_instance_id=process_instance_id).all()
|
||||||
|
assert len(remaining_tasks) == 3
|
||||||
|
|
||||||
def test_process_instance_delete(
|
def test_process_instance_delete(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -33,3 +33,5 @@ cypress/screenshots
|
||||||
|
|
||||||
# Editors
|
# Editors
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
|
/cypress.env
|
||||||
|
|
|
@ -30,6 +30,14 @@ if [[ -z "${CYPRESS_SPIFFWORKFLOW_FRONTEND_AUTH_WITH_KEYCLOAK:-}" ]]; then
|
||||||
export CYPRESS_SPIFFWORKFLOW_FRONTEND_AUTH_WITH_KEYCLOAK=true
|
export CYPRESS_SPIFFWORKFLOW_FRONTEND_AUTH_WITH_KEYCLOAK=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -f cypress.env ]]; then
|
||||||
|
# shellcheck disable=1091
|
||||||
|
source cypress.env
|
||||||
|
else
|
||||||
|
>&2 echo "ERROR: This requires a cypress.env file to run. You may be able to use generate_pp1_cypress_env_configs."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
cypress_run_file="/var/tmp/cypress_run"
|
cypress_run_file="/var/tmp/cypress_run"
|
||||||
echo "Recording stats to ${cypress_run_file}"
|
echo "Recording stats to ${cypress_run_file}"
|
||||||
|
|
||||||
|
@ -44,7 +52,6 @@ for attempt in $(seq 1 "$ATTEMPTS" ); do
|
||||||
|
|
||||||
start_time=$(date +%s)
|
start_time=$(date +%s)
|
||||||
success="false"
|
success="false"
|
||||||
# spec_pattern="cypress/pilot/**/*.cy.{js,jsx,ts,tsx}"
|
|
||||||
spec_pattern="cypress/pilot/**/*.cy.{js,jsx,ts,tsx}"
|
spec_pattern="cypress/pilot/**/*.cy.{js,jsx,ts,tsx}"
|
||||||
if ./node_modules/.bin/cypress "$command" -c specPattern="${spec_pattern}" --e2e --browser chrome "$@"; then
|
if ./node_modules/.bin/cypress "$command" -c specPattern="${spec_pattern}" --e2e --browser chrome "$@"; then
|
||||||
success="true"
|
success="true"
|
||||||
|
|
|
@ -93,7 +93,7 @@ describe.only('Software and Licenses Path - Without Files', () => {
|
||||||
Cypress._.times(1, () => {
|
Cypress._.times(1, () => {
|
||||||
|
|
||||||
//Everyone approves with CP
|
//Everyone approves with CP
|
||||||
it('Everyone approves with CP', () => {
|
it.only('Everyone approves with CP', () => {
|
||||||
let username = Cypress.env('requestor_username');
|
let username = Cypress.env('requestor_username');
|
||||||
let password = Cypress.env('requestor_password');
|
let password = Cypress.env('requestor_password');
|
||||||
cy.log('=====username : ' + username);
|
cy.log('=====username : ' + username);
|
||||||
|
@ -103,23 +103,10 @@ describe.only('Software and Licenses Path - Without Files', () => {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
|
|
||||||
cy.contains('Start New +').click();
|
cy.contains('Start New +').click();
|
||||||
cy.contains('Request Goods or Services');
|
cy.contains('Request Goods or Services').click();
|
||||||
|
|
||||||
cy.runPrimaryBpmnFile(true);
|
cy.runPrimaryBpmnFile(true);
|
||||||
|
|
||||||
/* cy.contains('Please select the type of request to start the process.');
|
|
||||||
// wait a second to ensure we can click the radio button
|
|
||||||
|
|
||||||
cy.wait(2000);
|
|
||||||
cy.get('input#root-procurement').click();
|
|
||||||
cy.wait(2000);
|
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
|
||||||
.contains(/^Submit$/)
|
|
||||||
.click();
|
|
||||||
*/
|
|
||||||
|
|
||||||
cy.contains(
|
cy.contains(
|
||||||
'Request Goods or Services',
|
'Request Goods or Services',
|
||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
|
|
|
@ -63,6 +63,7 @@ Cypress.Commands.add('login', (username, password) => {
|
||||||
|
|
||||||
Cypress.Commands.add('logout', (_selector, ..._args) => {
|
Cypress.Commands.add('logout', (_selector, ..._args) => {
|
||||||
cy.get('#user-profile-toggletip').click();
|
cy.get('#user-profile-toggletip').click();
|
||||||
|
cy.wait(2000);
|
||||||
cy.getBySel('logout-button').click();
|
cy.getBySel('logout-button').click();
|
||||||
if (Cypress.env('SPIFFWORKFLOW_FRONTEND_AUTH_WITH_KEYCLOAK') === true) {
|
if (Cypress.env('SPIFFWORKFLOW_FRONTEND_AUTH_WITH_KEYCLOAK') === true) {
|
||||||
// otherwise we can click logout, quickly load the next page, and the javascript
|
// otherwise we can click logout, quickly load the next page, and the javascript
|
||||||
|
|
Loading…
Reference in New Issue