This commit is contained in:
mike cullerton 2022-11-21 18:02:38 -05:00
commit e9724b9337
9 changed files with 126 additions and 51 deletions

View File

@ -33,7 +33,7 @@ class ProcessGroup:
def __post_init__(self) -> None: def __post_init__(self) -> None:
"""__post_init__.""" """__post_init__."""
self.sort_index = self.id self.sort_index = self.display_name
def __eq__(self, other: Any) -> bool: def __eq__(self, other: Any) -> bool:
"""__eq__.""" """__eq__."""

View File

@ -0,0 +1,43 @@
"""Get_env."""
from typing import Any
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.group import GroupNotFoundError
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,
)
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.models.user import UserNotFoundError
from spiffworkflow_backend.scripts.script import Script
from spiffworkflow_backend.services.user_service import UserService
class AddUserToGroup(Script):
"""AddUserToGroup."""
def get_description(self) -> str:
"""Get_description."""
return """Add a given user to a given group."""
def run(
self,
script_attributes_context: ScriptAttributesContext,
*args: Any,
**kwargs: Any,
) -> Any:
"""Run."""
username = args[0]
group_identifier = args[1]
user = UserModel.query.filter_by(username=username).first()
if user is None:
raise UserNotFoundError(
f"Script 'add_user_to_group' could not find a user with username: {username}"
)
group = GroupModel.query.filter_by(identifier=group_identifier).first()
if group is None:
raise GroupNotFoundError(
f"Script 'add_user_to_group' could not find group with identifier '{group_identifier}'."
)
UserService.add_user_to_group(user, group)

View File

@ -32,7 +32,9 @@ describe('process-groups', () => {
cy.contains('Delete').click(); cy.contains('Delete').click();
cy.contains('Are you sure'); cy.contains('Are you sure');
cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); cy.getBySel('delete-process-group-button-modal-confirmation-dialog')
.find('.cds--btn--danger')
.click();
cy.url().should('include', `process-groups`); cy.url().should('include', `process-groups`);
cy.contains(groupId).should('not.exist'); cy.contains(groupId).should('not.exist');
}); });

View File

@ -1,3 +1,5 @@
import { modifyProcessModelPath } from '../../src/helpers';
describe('process-models', () => { describe('process-models', () => {
beforeEach(() => { beforeEach(() => {
cy.login(); cy.login();
@ -9,14 +11,19 @@ describe('process-models', () => {
it('can perform crud operations', () => { it('can perform crud operations', () => {
const uuid = () => Cypress._.random(0, 1e6); const uuid = () => Cypress._.random(0, 1e6);
const id = uuid(); const id = uuid();
const groupId = 'acceptance-tests-group-one'; const groupId = 'misc/acceptance-tests-group-one';
const groupDisplayName = 'Acceptance Tests Group One'; const groupDisplayName = 'Acceptance Tests Group One';
const modelDisplayName = `Test Model 2 ${id}`; const modelDisplayName = `Test Model 2 ${id}`;
const newModelDisplayName = `${modelDisplayName} edited`;
const modelId = `test-model-2-${id}`; const modelId = `test-model-2-${id}`;
const newModelDisplayName = `${modelDisplayName} edited`;
cy.contains('Misc').click();
cy.wait(500);
cy.contains(groupDisplayName).click(); cy.contains(groupDisplayName).click();
cy.createModel(groupId, modelId, modelDisplayName); cy.createModel(groupId, modelId, modelDisplayName);
cy.url().should('include', `process-models/${groupId}:${modelId}`); cy.url().should(
'include',
`process-models/${modifyProcessModelPath(groupId)}:${modelId}`
);
cy.contains(`Process Model: ${modelDisplayName}`); cy.contains(`Process Model: ${modelDisplayName}`);
cy.contains('Edit process model').click(); cy.contains('Edit process model').click();
@ -34,15 +41,21 @@ describe('process-models', () => {
cy.getBySel('delete-process-model-button').click(); cy.getBySel('delete-process-model-button').click();
cy.contains('Are you sure'); cy.contains('Are you sure');
cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); cy.getBySel('delete-process-model-button-modal-confirmation-dialog')
cy.url().should('include', `process-groups/${groupId}`); .find('.cds--btn--danger')
.click();
cy.url().should(
'include',
`process-groups/${modifyProcessModelPath(groupId)}`
);
cy.contains(modelId).should('not.exist'); cy.contains(modelId).should('not.exist');
}); });
it.only('can create new bpmn, dmn, and json files', () => { it('can create new bpmn, dmn, and json files', () => {
const uuid = () => Cypress._.random(0, 1e6); const uuid = () => Cypress._.random(0, 1e6);
const id = uuid(); const id = uuid();
const groupId = 'misc/acceptance-tests-group-one'; const directParentGroupId = 'acceptance-tests-group-one';
const groupId = `misc/${directParentGroupId}`;
const groupDisplayName = 'Acceptance Tests Group One'; const groupDisplayName = 'Acceptance Tests Group One';
const modelDisplayName = `Test Model 2 ${id}`; const modelDisplayName = `Test Model 2 ${id}`;
const modelId = `test-model-2-${id}`; const modelId = `test-model-2-${id}`;
@ -52,11 +65,15 @@ describe('process-models', () => {
const jsonFileName = `json_test_file_${id}`; const jsonFileName = `json_test_file_${id}`;
cy.contains('Misc').click(); cy.contains('Misc').click();
cy.wait(500);
cy.contains(groupDisplayName).click(); cy.contains(groupDisplayName).click();
cy.createModel(groupId, modelId, modelDisplayName); cy.createModel(groupId, modelId, modelDisplayName);
cy.contains(groupId).click(); cy.contains(directParentGroupId).click();
cy.contains(modelId).click(); cy.contains(modelId).click();
cy.url().should('include', `process-models/${groupId}:${modelId}`); cy.url().should(
'include',
`process-models/${modifyProcessModelPath(groupId)}:${modelId}`
);
cy.contains(`Process Model: ${modelDisplayName}`); cy.contains(`Process Model: ${modelDisplayName}`);
cy.contains(`${bpmnFileName}.bpmn`).should('not.exist'); cy.contains(`${bpmnFileName}.bpmn`).should('not.exist');
cy.contains(`${dmnFileName}.dmn`).should('not.exist'); cy.contains(`${dmnFileName}.dmn`).should('not.exist');
@ -115,26 +132,34 @@ describe('process-models', () => {
cy.getBySel('delete-process-model-button').click(); cy.getBySel('delete-process-model-button').click();
cy.contains('Are you sure'); cy.contains('Are you sure');
cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); cy.getBySel('delete-process-model-button-modal-confirmation-dialog')
cy.url().should('include', `process-groups/${groupId}`); .find('.cds--btn--danger')
.click();
cy.url().should('include', `process-groups/${modifyProcessModelPath(groupId)}`);
cy.contains(modelId).should('not.exist'); cy.contains(modelId).should('not.exist');
}); });
it('can upload and run a bpmn file', () => { it('can upload and run a bpmn file', () => {
const uuid = () => Cypress._.random(0, 1e6); const uuid = () => Cypress._.random(0, 1e6);
const id = uuid(); const id = uuid();
const groupId = 'acceptance-tests-group-one'; const directParentGroupId = 'acceptance-tests-group-one';
const groupId = `misc/${directParentGroupId}`;
const groupDisplayName = 'Acceptance Tests Group One'; const groupDisplayName = 'Acceptance Tests Group One';
const modelDisplayName = `Test Model 2 ${id}`; const modelDisplayName = `Test Model 2 ${id}`;
const modelId = `test-model-2-${id}`; const modelId = `test-model-2-${id}`;
cy.contains('Add a process group'); cy.contains('Add a process group');
cy.contains('Misc').click();
cy.wait(500);
cy.contains(groupDisplayName).click(); cy.contains(groupDisplayName).click();
cy.createModel(groupId, modelId, modelDisplayName); cy.createModel(groupId, modelId, modelDisplayName);
cy.contains(`${groupId}`).click(); cy.contains(`${directParentGroupId}`).click();
cy.contains('Add a process model'); cy.contains('Add a process model');
cy.contains(modelId).click(); cy.contains(modelId).click();
cy.url().should('include', `process-models/${groupId}:${modelId}`); cy.url().should(
'include',
`process-models/${modifyProcessModelPath(groupId)}:${modelId}`
);
cy.contains(`Process Model: ${modelDisplayName}`); cy.contains(`Process Model: ${modelDisplayName}`);
cy.getBySel('upload-file-button').click(); cy.getBySel('upload-file-button').click();
@ -151,19 +176,28 @@ describe('process-models', () => {
cy.getBySel('process-instance-show-link').click(); cy.getBySel('process-instance-show-link').click();
cy.getBySel('process-instance-delete').click(); cy.getBySel('process-instance-delete').click();
cy.contains('Are you sure'); cy.contains('Are you sure');
cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); cy.getBySel('process-instance-delete-modal-confirmation-dialog')
.find('.cds--btn--danger')
.click();
// in breadcrumb // in breadcrumb
cy.contains(modelId).click(); cy.contains(modelId).click();
cy.getBySel('delete-process-model-button').click(); cy.getBySel('delete-process-model-button').click();
cy.contains('Are you sure'); cy.contains('Are you sure');
cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); cy.getBySel('delete-process-model-button-modal-confirmation-dialog')
cy.url().should('include', `process-groups/${groupId}`); .find('.cds--btn--danger')
.click();
cy.url().should(
'include',
`process-groups/${modifyProcessModelPath(groupId)}`
);
cy.contains(modelId).should('not.exist'); cy.contains(modelId).should('not.exist');
}); });
it('can paginate items', () => { it('can paginate items', () => {
cy.contains('Misc').click();
cy.wait(500);
cy.contains('Acceptance Tests Group One').click(); cy.contains('Acceptance Tests Group One').click();
cy.basicPaginationTest(); cy.basicPaginationTest();
}); });
@ -171,6 +205,6 @@ describe('process-models', () => {
it('can allow searching for model', () => { it('can allow searching for model', () => {
cy.getBySel('process-model-selection').click().type('model-3'); cy.getBySel('process-model-selection').click().type('model-3');
cy.contains('acceptance-tests-group-one/acceptance-tests-model-3').click(); cy.contains('acceptance-tests-group-one/acceptance-tests-model-3').click();
cy.contains('List').click(); cy.contains('Acceptance Tests Model 3');
}); });
}); });

View File

@ -1,12 +1,12 @@
const submitInputIntoFormField = (taskName, fieldKey, fieldValue) => { const submitInputIntoFormField = (taskName, fieldKey, fieldValue) => {
cy.contains(`Task: ${taskName}`); cy.contains(`Task: ${taskName}`, { timeout: 10000 });
cy.get(fieldKey).clear().type(fieldValue); cy.get(fieldKey).clear().type(fieldValue);
cy.contains('Submit').click(); cy.contains('Submit').click();
}; };
const checkFormFieldIsReadOnly = (formName, fieldKey) => { const checkFormFieldIsReadOnly = (formName, fieldKey) => {
cy.contains(`Task: ${formName}`); cy.contains(`Task: ${formName}`);
cy.get(fieldKey).invoke('attr', 'readonly').should('exist'); cy.get(fieldKey).invoke('attr', 'disabled').should('exist');
}; };
const checkTaskHasClass = (taskName, className) => { const checkTaskHasClass = (taskName, className) => {
@ -34,8 +34,6 @@ describe('tasks', () => {
// avoid reloading so we can click on the task link that appears on running the process instance // avoid reloading so we can click on the task link that appears on running the process instance
cy.runPrimaryBpmnFile(false); cy.runPrimaryBpmnFile(false);
cy.contains('my task').click();
submitInputIntoFormField( submitInputIntoFormField(
'get_user_generated_number_one', 'get_user_generated_number_one',
'#root_user_generated_number_1', '#root_user_generated_number_1',
@ -59,7 +57,6 @@ describe('tasks', () => {
'#root_user_generated_number_1' '#root_user_generated_number_1'
); );
cy.getBySel('form-nav-form3').should('have.text', 'form3 - Current');
cy.getBySel('form-nav-form3').click(); cy.getBySel('form-nav-form3').click();
submitInputIntoFormField( submitInputIntoFormField(
'get_user_generated_number_three', 'get_user_generated_number_three',
@ -110,21 +107,21 @@ describe('tasks', () => {
cy.contains('Status: complete'); cy.contains('Status: complete');
}); });
it('can paginate items', () => { // it('can paginate items', () => {
cy.navigateToProcessModel( // cy.navigateToProcessModel(
'Acceptance Tests Group One', // 'Acceptance Tests Group One',
'Acceptance Tests Model 2', // 'Acceptance Tests Model 1',
'acceptance-tests-model-2' // 'acceptance-tests-model-1'
); // );
//
// make sure we have some tasks // // make sure we have some tasks
cy.runPrimaryBpmnFile(); // cy.runPrimaryBpmnFile();
cy.runPrimaryBpmnFile(); // cy.runPrimaryBpmnFile();
cy.runPrimaryBpmnFile(); // cy.runPrimaryBpmnFile();
cy.runPrimaryBpmnFile(); // cy.runPrimaryBpmnFile();
cy.runPrimaryBpmnFile(); // cy.runPrimaryBpmnFile();
//
cy.navigateToHome(); // cy.navigateToHome();
cy.basicPaginationTest(); // cy.basicPaginationTest();
}); // });
}); });

View File

@ -1,4 +1,5 @@
import { string } from 'prop-types'; import { string } from 'prop-types';
import { modifyProcessModelPath } from '../../src/helpers';
// *********************************************** // ***********************************************
// This example commands.js shows you how to // This example commands.js shows you how to
@ -78,15 +79,16 @@ Cypress.Commands.add('createModel', (groupId, modelId, modelDisplayName) => {
cy.url().should( cy.url().should(
'include', 'include',
`process-models/${cy.modifyProcessModelPath(groupId)}:${modelId}` `process-models/${modifyProcessModelPath(groupId)}:${modelId}`
// `process-models/${groupId}:${modelId}`
); );
cy.contains(`Process Model: ${modelDisplayName}`); cy.contains(`Process Model: ${modelDisplayName}`);
}); });
Cypress.Commands.add('runPrimaryBpmnFile', (reload = true) => { Cypress.Commands.add('runPrimaryBpmnFile', (reload = true) => {
cy.contains('Run').click(); cy.contains('Run').click();
cy.contains(/Process Instance.*kicked off/);
if (reload) { if (reload) {
cy.contains(/Process Instance.*kicked off/);
cy.reload(true); cy.reload(true);
cy.contains(/Process Instance.*kicked off/).should('not.exist'); cy.contains(/Process Instance.*kicked off/).should('not.exist');
} }
@ -97,7 +99,7 @@ Cypress.Commands.add(
(groupDisplayName, modelDisplayName, modelIdentifier) => { (groupDisplayName, modelDisplayName, modelIdentifier) => {
cy.navigateToAdmin(); cy.navigateToAdmin();
cy.contains('Misc').click(); cy.contains('Misc').click();
cy.contains(`Process Group: Misc`); cy.contains(`Process Group: Misc`, { timeout: 10000 });
cy.contains(groupDisplayName).click(); cy.contains(groupDisplayName).click();
cy.contains(`Process Group: ${groupDisplayName}`); cy.contains(`Process Group: ${groupDisplayName}`);
// https://stackoverflow.com/q/51254946/6090676 // https://stackoverflow.com/q/51254946/6090676
@ -130,8 +132,3 @@ Cypress.Commands.add('modifyProcessModelPath', (path) => {
path.replace('/', ':'); path.replace('/', ':');
return path; return path;
}); });
Cypress.Commands.add('modifyProcessModelPath', (path) => {
path.replace('/', ':');
return path;
});

View File

@ -46,7 +46,7 @@ export default function ButtonWithConfirmation({
<Modal <Modal
open={showConfirmationPrompt} open={showConfirmationPrompt}
danger danger
data-qa="modal-confirmation-dialog" data-qa={`${dataQa}-modal-confirmation-dialog`}
modalHeading={description} modalHeading={description}
modalLabel={title} modalLabel={title}
primaryButtonText={confirmButtonLabel} primaryButtonText={confirmButtonLabel}

View File

@ -169,6 +169,7 @@ export default function ProcessGroupForm({
if (mode === 'edit') { if (mode === 'edit') {
buttons.push( buttons.push(
<ButtonWithConfirmation <ButtonWithConfirmation
data-qa="delete-process-group-button"
description={`Delete Process Group ${processGroup.id}?`} description={`Delete Process Group ${processGroup.id}?`}
onConfirmation={deleteProcessGroup} onConfirmation={deleteProcessGroup}
buttonLabel="Delete" buttonLabel="Delete"

View File

@ -190,6 +190,7 @@ export default function ReactFormEditor() {
)} )}
{params.file_name ? ( {params.file_name ? (
<ButtonWithConfirmation <ButtonWithConfirmation
data-qa="delete-process-model-file"
description={`Delete file ${params.file_name}?`} description={`Delete file ${params.file_name}?`}
onConfirmation={deleteFile} onConfirmation={deleteFile}
buttonLabel="Delete" buttonLabel="Delete"