From c7da932b5cf0287a378c44fdbf917101bbf31021 Mon Sep 17 00:00:00 2001 From: Yarin Dekel Date: Wed, 29 Aug 2018 17:31:54 +0300 Subject: added validation to name field Issue-ID: SDC-1690 Change-Id: I5332fbdcf67b6e21176faf40292a2164753d48c5 Signed-off-by: Yarin Dekel --- .../features/version/create/CreateVersionView.jsx | 2 +- .../CreateVersionView_snapshot-test.js.snap | 1 + .../src/features/workflow/create/CreateWorkflow.js | 9 +- .../workflow/create/CreateWorkflowView.jsx | 139 +++++++++++---------- .../__tests__/CreateWorkflowView_snapshot-test.js | 9 +- .../CreateWorkflowView_snapshot-test.js.snap | 1 + .../create/__tests__/createWorkflowSaga-test.js | 6 + .../workflow/create/createWorkflowConstants.js | 13 +- .../features/workflow/create/createWorkflowSaga.js | 55 ++++++-- .../src/features/workflow/workflowReducer.js | 13 +- .../src/main/frontend/src/i18n/languages.json | 3 +- 11 files changed, 157 insertions(+), 94 deletions(-) diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/create/CreateVersionView.jsx b/workflow-designer-ui/src/main/frontend/src/features/version/create/CreateVersionView.jsx index f3a2cccf..23e5db15 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/create/CreateVersionView.jsx +++ b/workflow-designer-ui/src/main/frontend/src/features/version/create/CreateVersionView.jsx @@ -60,7 +60,7 @@ class CreateVersionView extends Component { render() { const { closeCreateVersionModal } = this.props; return ( -
+
- workflowInputChange({ - name: val - }) - } - errorMessage={errorMessage} - isRequired - /> - + render() { + const { + workflowInputChange, + workflowDescription, + workflowName, + closeCreateWorkflowModal, + errorMessage + } = this.props; + return ( + +
+
+ + workflowInputChange({ + name: val + }) + } + errorMessage={errorMessage} + isRequired + /> + +
+
+ + +
-
- - -
-
- - ); -}; - -CreateWorkflowView.propTypes = { - submitWorkflow: PropTypes.func, - workflowInputChange: PropTypes.func, - workflowDescription: PropTypes.string, - workflowName: PropTypes.string, - closeCreateWorkflowModal: PropTypes.func, - workflowParams: PropTypes.object, - history: PropTypes.object, - errorMessage: PropTypes.string, - putNameError: PropTypes.func -}; + + ); + } +} CreateWorkflowView.defaultProps = { submitWorkflow: () => {}, workflowInputChange: () => {}, - closeCreateWorkflowModal: () => {} + closeCreateWorkflowModal: () => {}, + clearWorkflow: () => {} }; export default CreateWorkflowView; diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/CreateWorkflowView_snapshot-test.js b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/CreateWorkflowView_snapshot-test.js index a0d81c71..e34cea96 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/CreateWorkflowView_snapshot-test.js +++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/CreateWorkflowView_snapshot-test.js @@ -22,7 +22,14 @@ import CreateWorkflowView from 'features/workflow/create/CreateWorkflowView'; describe('New Workflow View Snapshot', () => { it('renders correctly', () => { - const tree = renderer.create().toJSON(); + const tree = renderer + .create( + {}} + clearWorkflow={() => {}} + /> + ) + .toJSON(); expect(tree).toMatchSnapshot(); }); diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/__snapshots__/CreateWorkflowView_snapshot-test.js.snap b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/__snapshots__/CreateWorkflowView_snapshot-test.js.snap index afd57303..59695f03 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/__snapshots__/CreateWorkflowView_snapshot-test.js.snap +++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/__tests__/__snapshots__/CreateWorkflowView_snapshot-test.js.snap @@ -2,6 +2,7 @@ exports[`New Workflow View Snapshot renders correctly 1`] = `
{ } }; const gen = watchSubmitWorkflow(action); + + /** + * expecting the error message to return as undefined + * from validateNameField method + */ + expect(gen.next().value).toEqual(undefined); expect(gen.next().value).toEqual( call(newWorkflowApi.createNewWorkflow, action.payload) ); diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowConstants.js b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowConstants.js index fc67605f..de18a1b4 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowConstants.js +++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowConstants.js @@ -18,9 +18,13 @@ export const NEW_VERSION = { baseId: null, description: null }; +export const MIN_NAME_LENGTH = 6; +export const MAX_NAME_LENGTH = 40; +export const CHARS_VALIDATION_EXP = /^[\w\s\d]+$/; export const WORKFLOW_INPUT_CHANGE = 'createWorkflow/INPUT_CHANGE'; export const SUBMIT_WORKFLOW = 'createWorkflow/SUBMIT_WORKFLOW'; -export const EMPTY_NAME_ERROR = 'createWorkflow/EMPTY_NAME_ERROR'; +export const VALIDATION_ERROR = 'createWorkflow/VALIDATION_ERROR'; +export const CLEAR_VALIDATION_ERROR = 'createWorkflow/CLEAR_VALIDATION_ERROR'; export const inputChangeAction = payload => ({ type: WORKFLOW_INPUT_CHANGE, @@ -32,6 +36,9 @@ export const submitWorkflowAction = payload => ({ payload }); -export const putNameError = () => ({ - type: EMPTY_NAME_ERROR +export const putValidationError = payload => ({ + type: VALIDATION_ERROR, + payload }); + +export const clearValidationError = () => ({ type: CLEAR_VALIDATION_ERROR }); diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowSaga.js b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowSaga.js index 7f988002..e918556b 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowSaga.js +++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/create/createWorkflowSaga.js @@ -14,33 +14,66 @@ * limitations under the License. */ import { takeEvery, call, put } from 'redux-saga/effects'; -import { SUBMIT_WORKFLOW } from 'features/workflow/create/createWorkflowConstants'; +import { I18n } from 'react-redux-i18n'; + +import { + SUBMIT_WORKFLOW, + NEW_VERSION, + MAX_NAME_LENGTH, + MIN_NAME_LENGTH, + CHARS_VALIDATION_EXP, + putValidationError +} from 'features/workflow/create/createWorkflowConstants'; import { setWorkflowAction, clearWorkflowAction } from 'features/workflow/workflowConstants'; +import { hideModalAction } from 'shared/modal/modalWrapperActions'; import newWorkflowApi from 'features/workflow/create/createWorkflowApi'; import { genericNetworkErrorAction } from 'wfapp/appConstants'; import { submitVersionAction } from 'features/version/create/createVersionConstants'; -import { NEW_VERSION } from 'features/workflow/create/createWorkflowConstants'; export function* watchSubmitWorkflow(action) { try { - const workflow = yield call( - newWorkflowApi.createNewWorkflow, - action.payload - ); - //Calling to create empty version - const workflowId = workflow.id; - const { history } = action.payload; - yield put(submitVersionAction({ history, workflowId, ...NEW_VERSION })); - yield put(setWorkflowAction(workflow)); + const { name } = action.payload; + const validationError = yield validateNameField(name); + if (validationError) { + yield put(putValidationError(validationError)); + } else { + const workflow = yield call( + newWorkflowApi.createNewWorkflow, + action.payload + ); + //Calling to create empty version + const workflowId = workflow.id; + const { history } = action.payload; + yield put( + submitVersionAction({ history, workflowId, ...NEW_VERSION }) + ); + yield put(setWorkflowAction(workflow)); + yield put(hideModalAction()); + } } catch (error) { yield put(clearWorkflowAction); yield put(genericNetworkErrorAction(error)); } } +export function validateNameField(name) { + let errorMessage; + if (!name) { + errorMessage = I18n.t('workflow.errorMessages.emptyName'); + } else if (!CHARS_VALIDATION_EXP.test(name)) { + errorMessage = I18n.t('workflow.errorMessages.invalidCharacters'); + } else if (name.length < MIN_NAME_LENGTH || name.length > MAX_NAME_LENGTH) { + errorMessage = I18n.t('workflow.errorMessages.nameFieldLength', { + minValue: 6, + maxValue: 40 + }); + } + return errorMessage; +} + export function* watchWorkflow() { yield takeEvery(SUBMIT_WORKFLOW, watchSubmitWorkflow); } diff --git a/workflow-designer-ui/src/main/frontend/src/features/workflow/workflowReducer.js b/workflow-designer-ui/src/main/frontend/src/features/workflow/workflowReducer.js index 3b7e17b4..c0b0557d 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/workflow/workflowReducer.js +++ b/workflow-designer-ui/src/main/frontend/src/features/workflow/workflowReducer.js @@ -14,10 +14,10 @@ * limitations under the License. */ -import { I18n } from 'react-redux-i18n'; import { WORKFLOW_INPUT_CHANGE, - EMPTY_NAME_ERROR + VALIDATION_ERROR, + CLEAR_VALIDATION_ERROR } from 'features/workflow/create/createWorkflowConstants'; import { SET_WORKFLOW, @@ -37,10 +37,15 @@ function workflowReducer(state = {}, action) { return { ...action.payload }; - case EMPTY_NAME_ERROR: + case VALIDATION_ERROR: return { ...state, - error: I18n.t('workflow.errorMessages.emptyName') + error: action.payload + }; + case CLEAR_VALIDATION_ERROR: + return { + ...state, + error: '' }; default: return state; diff --git a/workflow-designer-ui/src/main/frontend/src/i18n/languages.json b/workflow-designer-ui/src/main/frontend/src/i18n/languages.json index 36546452..42f2475e 100644 --- a/workflow-designer-ui/src/main/frontend/src/i18n/languages.json +++ b/workflow-designer-ui/src/main/frontend/src/i18n/languages.json @@ -64,7 +64,8 @@ "errorMessages": { "alreadyExists": "Already exists", "invalidCharacters": "Alphanumeric and underscore only", - "emptyName": "Field is required" + "emptyName": "Field is required", + "nameFieldLength": "Name must be at least %{minValue} characters and no more than %{maxValue} characters" }, "composition": { "bpmnError" : "BPMN.IO Error", -- cgit 1.2.3-korg