From f290150eb7dd14064e3294adbcdf33955eb4e4b4 Mon Sep 17 00:00:00 2001 From: pkupczyk <piotr.kupczyk@id.ethz.ch> Date: Mon, 30 Dec 2019 12:44:06 +0100 Subject: [PATCH] SSDM-7583 : ObjectTypeForm - unit tests for more handlers --- .../types/objectType/ObjectType.jsx | 4 +- .../objectType/ObjectTypeHandlerRemove.js | 52 +-- .../objectType/ObjectTypeHandlerValidate.js | 11 +- .../srcTest/js/common/ComponentState.js | 12 +- .../objectType/ObjectTypeHandlerLoad.test.js | 225 ++++++++++++ .../ObjectTypeHandlerOrderChange.test.js | 134 +++++++ .../ObjectTypeHandlerRemove.test.js | 326 ++++++++++++++++++ .../ObjectTypeHandlerSelectionChange.test.js | 49 +++ .../ObjectTypeHandlerValidate.test.js | 255 ++++++++++++++ 9 files changed, 1039 insertions(+), 29 deletions(-) create mode 100644 openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerLoad.test.js create mode 100644 openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerOrderChange.test.js create mode 100644 openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerRemove.test.js create mode 100644 openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerSelectionChange.test.js create mode 100644 openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerValidate.test.js diff --git a/openbis_ng_ui/src/js/components/types/objectType/ObjectType.jsx b/openbis_ng_ui/src/js/components/types/objectType/ObjectType.jsx index 679e93880a8..71bcb46cee3 100644 --- a/openbis_ng_ui/src/js/components/types/objectType/ObjectType.jsx +++ b/openbis_ng_ui/src/js/components/types/objectType/ObjectType.jsx @@ -140,14 +140,14 @@ class ObjectType extends React.PureComponent { new ObjectTypeHandlerRemove( this.state, this.setState.bind(this) - ).executeRemoveConfirm() + ).executeRemove(true) } handleRemoveCancel() { new ObjectTypeHandlerRemove( this.state, this.setState.bind(this) - ).executeRemoveCancel() + ).executeCancel() } handleSave() { diff --git a/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerRemove.js b/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerRemove.js index 3ab191f52e6..4a7be869ab2 100644 --- a/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerRemove.js +++ b/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerRemove.js @@ -6,37 +6,39 @@ export default class ObjectTypeHandlerRemove { this.setState = setState } - executeRemove() { + executeRemove(confirmed = false) { const { selection } = this.state if (selection.type === 'section') { - this.handleRemoveSection(selection.params.id) + this.handleRemoveSection(selection.params.id, confirmed) } else if (selection.type === 'property') { - this.handleRemoveProperty(selection.params.id) + this.handleRemoveProperty(selection.params.id, confirmed) } } - executeRemoveConfirm() { - this.setState({ - removeSectionDialogOpen: false, - removePropertyDialogOpen: false - }) - this.executeRemove() - } - - executeRemoveCancel() { - this.setState({ - removeSectionDialogOpen: false, - removePropertyDialogOpen: false - }) + executeCancel() { + const { selection } = this.state + if (selection.type === 'section') { + this.setState({ + removeSectionDialogOpen: false + }) + } else if (selection.type === 'property') { + this.setState({ + removePropertyDialogOpen: false + }) + } } - handleRemoveSection(sectionId) { - const { sections, properties, removeSectionDialogOpen } = this.state + handleRemoveSection(sectionId, confirmed) { + const { sections, properties } = this.state const sectionIndex = sections.findIndex(section => section.id === sectionId) const section = sections[sectionIndex] - if (this.isSectionUsed(section) && !removeSectionDialogOpen) { + if (confirmed) { + this.setState({ + removeSectionDialogOpen: false + }) + } else if (this.isSectionUsed(section)) { this.setState({ removeSectionDialogOpen: true }) @@ -60,15 +62,19 @@ export default class ObjectTypeHandlerRemove { })) } - handleRemoveProperty(propertyId) { - const { sections, properties, removePropertyDialogOpen } = this.state + handleRemoveProperty(propertyId, confirmed) { + const { sections, properties } = this.state const propertyIndex = properties.findIndex( property => property.id === propertyId ) const property = properties[propertyIndex] - if (this.isPropertyUsed(property) && !removePropertyDialogOpen) { + if (confirmed) { + this.setState({ + removePropertyDialogOpen: false + }) + } else if (this.isPropertyUsed(property)) { this.setState({ removePropertyDialogOpen: true }) @@ -114,6 +120,6 @@ export default class ObjectTypeHandlerRemove { } isPropertyUsed(property) { - return property.usages !== 0 + return _.isFinite(property.usages) && property.usages !== 0 } } diff --git a/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerValidate.js b/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerValidate.js index 4a2ad1c4172..1be4cfa73b8 100644 --- a/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerValidate.js +++ b/openbis_ng_ui/src/js/components/types/objectType/ObjectTypeHandlerValidate.js @@ -24,7 +24,7 @@ export default class ObjectTypeHandlerValidate { const { validate, type, properties } = this.getState() if (!validate) { - return + return true } const [typeErrors, typeErrorsMap] = this.validateType(type) @@ -66,11 +66,16 @@ export default class ObjectTypeHandlerValidate { return { type: newType, - properties: newProperties, - selection: errorSelection ? errorSelection : state.selection + properties: newProperties } }) + if (errorSelection) { + this.setState({ + selection: errorSelection + }) + } + return _.isEmpty(typeErrors) && _.isEmpty(propertiesErrors) } diff --git a/openbis_ng_ui/srcTest/js/common/ComponentState.js b/openbis_ng_ui/srcTest/js/common/ComponentState.js index 1996729c244..c4f443c6c9e 100644 --- a/openbis_ng_ui/srcTest/js/common/ComponentState.js +++ b/openbis_ng_ui/srcTest/js/common/ComponentState.js @@ -11,8 +11,14 @@ class ComponentState { return this.state } + getGetState() { + return () => { + return this.getState() + } + } + getSetState() { - return newStateOrFunction => { + return (newStateOrFunction, callback) => { let changes if (_.isFunction(newStateOrFunction)) { @@ -22,6 +28,10 @@ class ComponentState { } this.state = { ...this.state, ...changes } + + if (callback) { + callback() + } } } diff --git a/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerLoad.test.js b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerLoad.test.js new file mode 100644 index 00000000000..20961dd41fb --- /dev/null +++ b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerLoad.test.js @@ -0,0 +1,225 @@ +import ObjectTypeHandlerLoad from '../../../../../src/js/components/types/objectType/ObjectTypeHandlerLoad.js' +import ComponentState from '../../../common/ComponentState.js' + +describe('ObjectTypeHandlerLoadTest', () => { + test('load success', done => { + const componentState = new ComponentState({}) + const facade = { + loadType: jest.fn(), + loadUsages: jest.fn() + } + + facade.loadType.mockReturnValueOnce( + Promise.resolve({ + code: 'TYPE_CODE', + description: 'TYPE_DESCRIPTION', + listable: true, + showContainer: true, + showParents: true, + showParentMetadata: true, + autoGeneratedCode: true, + generatedCodePrefix: 'TYPE_CODE_PREFIX', + subcodeUnique: true, + validationPlugin: { name: 'TYPE_VALIDATION_PLUGIN' }, + propertyAssignments: [ + { + propertyType: { + code: 'PROPERTY_0_CODE', + label: 'PROPERTY_0_LABEL', + description: 'PROPERTY_0_DESCRIPTION', + dataType: 'VARCHAR', + schema: null, + transformation: null + }, + plugin: { name: 'PROPERTY_0_PLUGIN' }, + mandatory: true, + section: 'SECTION_0', + showInEditView: true, + showRawValueInForms: true + }, + { + propertyType: { + code: 'PROPERTY_1_CODE', + label: 'PROPERTY_1_LABEL', + description: 'PROPERTY_1_DESCRIPTION', + dataType: 'CONTROLLED_VOCABULARY', + vocabulary: { + code: 'PROPERTY_1_VOCABULARY_CODE' + }, + schema: null, + transformation: null + }, + plugin: null, + mandatory: false, + section: 'SECTION_0', + showInEditView: false, + showRawValueInForms: false + }, + { + propertyType: { + code: 'PROPERTY_2_CODE', + label: 'PROPERTY_2_LABEL', + description: 'PROPERTY_2_DESCRIPTION', + dataType: 'MATERIAL', + materialType: { + code: 'PROPERTY_2_MATERIAL_TYPE_CODE' + }, + schema: null, + transformation: null + }, + plugin: null, + mandatory: false, + section: null, + showInEditView: false, + showRawValueInForms: false + } + ] + }) + ) + facade.loadUsages.mockReturnValueOnce( + Promise.resolve({ + type: 3, + property: { + PROPERTY_0_CODE: 2, + PROPERTY_1_CODE: 1 + } + }) + ) + + execute(123, componentState, facade).finally(() => { + expect(facade.loadType).toBeCalledWith(123) + expect(facade.loadUsages).toBeCalledWith(123) + + const state = componentState.getState() + + delete state.type.original + state.properties.forEach(property => { + delete property.original + }) + + componentState.assertState({ + loading: false, + selection: null, + sections: [ + { + id: 'section-0', + name: 'SECTION_0', + properties: ['property-0', 'property-1'] + }, + { + id: 'section-1', + name: null, + properties: ['property-2'] + } + ], + properties: [ + { + code: 'PROPERTY_0_CODE', + dataType: 'VARCHAR', + description: 'PROPERTY_0_DESCRIPTION', + errors: {}, + id: 'property-0', + label: 'PROPERTY_0_LABEL', + mandatory: true, + materialType: null, + plugin: 'PROPERTY_0_PLUGIN', + schema: null, + section: 'section-0', + showInEditView: true, + showRawValueInForms: true, + transformation: null, + usages: 2, + vocabulary: null + }, + { + code: 'PROPERTY_1_CODE', + dataType: 'CONTROLLED_VOCABULARY', + description: 'PROPERTY_1_DESCRIPTION', + errors: {}, + id: 'property-1', + label: 'PROPERTY_1_LABEL', + mandatory: false, + materialType: null, + plugin: null, + schema: null, + section: 'section-0', + showInEditView: false, + showRawValueInForms: false, + transformation: null, + usages: 1, + vocabulary: 'PROPERTY_1_VOCABULARY_CODE' + }, + { + code: 'PROPERTY_2_CODE', + dataType: 'MATERIAL', + description: 'PROPERTY_2_DESCRIPTION', + errors: {}, + id: 'property-2', + label: 'PROPERTY_2_LABEL', + mandatory: false, + materialType: 'PROPERTY_2_MATERIAL_TYPE_CODE', + plugin: null, + schema: null, + section: 'section-1', + showInEditView: false, + showRawValueInForms: false, + transformation: null, + usages: 0, + vocabulary: null + } + ], + type: { + autoGeneratedCode: true, + code: 'TYPE_CODE', + description: 'TYPE_DESCRIPTION', + errors: {}, + generatedCodePrefix: 'TYPE_CODE_PREFIX', + listable: true, + showContainer: true, + showParentMetadata: true, + showParents: true, + subcodeUnique: true, + usages: 3, + validationPlugin: 'TYPE_VALIDATION_PLUGIN' + }, + propertiesCounter: 3, + sectionsCounter: 2, + removePropertyDialogOpen: false, + removeSectionDialogOpen: false + }) + + done() + }) + }) + + test('load failure', done => { + const componentState = new ComponentState({}) + const facade = { + loadType: jest.fn(), + loadUsages: jest.fn(), + catch: jest.fn() + } + + facade.loadType.mockReturnValueOnce(Promise.reject('Server unavailable')) + facade.loadUsages.mockReturnValueOnce(Promise.resolve({})) + + execute(123, componentState, facade).finally(() => { + expect(facade.loadType).toBeCalledWith(123) + expect(facade.loadUsages).toBeCalledWith(123) + expect(facade.catch).toBeCalledWith('Server unavailable') + + componentState.assertState({ loading: false }) + + done() + }) + }) +}) + +const execute = (objectId, componentState, facade) => { + return new ObjectTypeHandlerLoad( + objectId, + componentState.getState(), + componentState.getSetState(), + facade + ).execute() +} diff --git a/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerOrderChange.test.js b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerOrderChange.test.js new file mode 100644 index 00000000000..b20e2b7f39b --- /dev/null +++ b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerOrderChange.test.js @@ -0,0 +1,134 @@ +import ObjectTypeHandlerOrderChange from '../../../../../src/js/components/types/objectType/ObjectTypeHandlerOrderChange.js' +import ComponentState from '../../../common/ComponentState.js' + +describe('ObjectTypeHandlerOrderChangeTest', () => { + test('section', () => { + const componentState = new ComponentState({ + sections: [ + { + id: 'section-0' + }, + { + id: 'section-1' + }, + { + id: 'section-2' + } + ] + }) + + execute(componentState, 'section', { + fromIndex: 2, + toIndex: 0 + }) + + componentState.assertState({ + sections: [ + { + id: 'section-2' + }, + { + id: 'section-0' + }, + { + id: 'section-1' + } + ] + }) + }) + + test('property', () => { + const componentState = new ComponentState({ + sections: [ + { + id: 'section-0', + properties: ['property-0', 'property-1'] + }, + { + id: 'section-1', + properties: [] + }, + { + id: 'section-2', + properties: ['property-2', 'property-3', 'property-4'] + } + ], + properties: [ + { id: 'property-0', section: 'section-0' }, + { id: 'property-1', section: 'section-0' }, + { id: 'property-2', section: 'section-2' }, + { id: 'property-3', section: 'section-2' }, + { id: 'property-4', section: 'section-2' } + ] + }) + + execute(componentState, 'property', { + fromSectionId: 'section-2', + toSectionId: 'section-2', + fromIndex: 0, + toIndex: 1 + }) + + componentState.assertState({ + sections: [ + { + id: 'section-0', + properties: ['property-0', 'property-1'] + }, + { + id: 'section-1', + properties: [] + }, + { + id: 'section-2', + properties: ['property-3', 'property-2', 'property-4'] + } + ], + properties: [ + { id: 'property-0', section: 'section-0' }, + { id: 'property-1', section: 'section-0' }, + { id: 'property-2', section: 'section-2' }, + { id: 'property-3', section: 'section-2' }, + { id: 'property-4', section: 'section-2' } + ] + }) + + execute(componentState, 'property', { + fromSectionId: 'section-2', + toSectionId: 'section-0', + fromIndex: 1, + toIndex: 1 + }) + + componentState.assertState({ + sections: [ + { + id: 'section-0', + properties: ['property-0', 'property-2', 'property-1'] + }, + { + id: 'section-1', + properties: [] + }, + { + id: 'section-2', + properties: ['property-3', 'property-4'] + } + ], + properties: [ + { id: 'property-0', section: 'section-0' }, + { id: 'property-1', section: 'section-0' }, + { id: 'property-2', section: 'section-0' }, + { id: 'property-3', section: 'section-2' }, + { id: 'property-4', section: 'section-2' } + ] + }) + }) +}) + +const execute = (componentState, type, params) => { + new ObjectTypeHandlerOrderChange( + componentState.getState(), + componentState.getSetState() + ).execute(type, params) +} diff --git a/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerRemove.test.js b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerRemove.test.js new file mode 100644 index 00000000000..8b8622681f6 --- /dev/null +++ b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerRemove.test.js @@ -0,0 +1,326 @@ +import ObjectTypeHandlerRemove from '../../../../../src/js/components/types/objectType/ObjectTypeHandlerRemove.js' +import ComponentState from '../../../common/ComponentState.js' + +describe('ObjectTypeHandlerRemoveTest', () => { + test('section not used', () => { + const componentState = new ComponentState({ + selection: { + type: 'section', + params: { + id: 'section-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0', 'property-1'] + }, + { + id: 'section-1', + properties: ['property-2', 'property-3', 'property-4'] + } + ], + properties: [ + { id: 'property-0', section: 'section-0' }, + { id: 'property-1', section: 'section-0' }, + { id: 'property-2', section: 'section-1' }, + { id: 'property-3', section: 'section-1' }, + { id: 'property-4', section: 'section-1' } + ] + }) + + executeRemove(componentState) + + componentState.assertState({ + selection: null, + sections: [ + { + id: 'section-1', + properties: ['property-2', 'property-3', 'property-4'] + } + ], + properties: [ + { id: 'property-2', section: 'section-1' }, + { id: 'property-3', section: 'section-1' }, + { id: 'property-4', section: 'section-1' } + ] + }) + }) + + test('section used and confirmed', () => { + const componentState = new ComponentState({ + selection: { + type: 'section', + params: { + id: 'section-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeRemove(componentState) + executeRemove(componentState) + + componentState.assertState({ + removeSectionDialogOpen: true, + selection: { + type: 'section', + params: { + id: 'section-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeRemove(componentState, true) + + componentState.assertState({ + removeSectionDialogOpen: false, + selection: null, + sections: [], + properties: [] + }) + }) + + test('section used and cancelled', () => { + const componentState = new ComponentState({ + selection: { + type: 'section', + params: { + id: 'section-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeRemove(componentState) + executeRemove(componentState) + + componentState.assertState({ + removeSectionDialogOpen: true, + selection: { + type: 'section', + params: { + id: 'section-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeCancel(componentState) + + componentState.assertState({ + removeSectionDialogOpen: false, + selection: { + type: 'section', + params: { + id: 'section-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + }) + + test('property not used', () => { + const componentState = new ComponentState({ + selection: { + type: 'property', + params: { + id: 'property-3' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0', 'property-1'] + }, + { + id: 'section-1', + properties: ['property-2', 'property-3', 'property-4'] + } + ], + properties: [ + { id: 'property-0', section: 'section-0' }, + { id: 'property-1', section: 'section-0' }, + { id: 'property-2', section: 'section-1' }, + { id: 'property-3', section: 'section-1' }, + { id: 'property-4', section: 'section-1' } + ] + }) + + executeRemove(componentState) + + componentState.assertState({ + selection: null, + sections: [ + { + id: 'section-0', + properties: ['property-0', 'property-1'] + }, + { + id: 'section-1', + properties: ['property-2', 'property-4'] + } + ], + properties: [ + { id: 'property-0', section: 'section-0' }, + { id: 'property-1', section: 'section-0' }, + { id: 'property-2', section: 'section-1' }, + { id: 'property-4', section: 'section-1' } + ] + }) + }) + + test('property used and confirmed', () => { + const componentState = new ComponentState({ + selection: { + type: 'property', + params: { + id: 'property-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeRemove(componentState) + executeRemove(componentState) + + componentState.assertState({ + removePropertyDialogOpen: true, + selection: { + type: 'property', + params: { + id: 'property-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeRemove(componentState, true) + + componentState.assertState({ + removePropertyDialogOpen: false, + selection: null, + sections: [ + { + id: 'section-0', + properties: [] + } + ], + properties: [] + }) + }) + + test('property used and cancelled', () => { + const componentState = new ComponentState({ + selection: { + type: 'property', + params: { + id: 'property-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeRemove(componentState) + executeRemove(componentState) + + componentState.assertState({ + removePropertyDialogOpen: true, + selection: { + type: 'property', + params: { + id: 'property-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + + executeCancel(componentState) + + componentState.assertState({ + removePropertyDialogOpen: false, + selection: { + type: 'property', + params: { + id: 'property-0' + } + }, + sections: [ + { + id: 'section-0', + properties: ['property-0'] + } + ], + properties: [{ id: 'property-0', section: 'section-0', usages: 1 }] + }) + }) +}) + +const executeRemove = (componentState, confirmed) => { + new ObjectTypeHandlerRemove( + componentState.getState(), + componentState.getSetState() + ).executeRemove(confirmed) +} + +const executeCancel = componentState => { + new ObjectTypeHandlerRemove( + componentState.getState(), + componentState.getSetState() + ).executeCancel() +} diff --git a/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerSelectionChange.test.js b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerSelectionChange.test.js new file mode 100644 index 00000000000..834e128f3bb --- /dev/null +++ b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerSelectionChange.test.js @@ -0,0 +1,49 @@ +import ObjectTypeHandlerSelectionChange from '../../../../../src/js/components/types/objectType/ObjectTypeHandlerSelectionChange.js' +import ComponentState from '../../../common/ComponentState.js' + +describe('ObjectTypeHandlerSelectionChangeTest', () => { + test('section', () => { + const componentState = new ComponentState({ + selection: null + }) + + execute(componentState, 'section', { + id: 'section-0' + }) + + componentState.assertState({ + selection: { + type: 'section', + params: { + id: 'section-0' + } + } + }) + }) + + test('property', () => { + const componentState = new ComponentState({ + selection: null + }) + + execute(componentState, 'property', { + id: 'property-0' + }) + + componentState.assertState({ + selection: { + type: 'property', + params: { + id: 'property-0' + } + } + }) + }) +}) + +const execute = (componentState, type, params) => { + new ObjectTypeHandlerSelectionChange( + componentState.getState(), + componentState.getSetState() + ).execute(type, params) +} diff --git a/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerValidate.test.js b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerValidate.test.js new file mode 100644 index 00000000000..4e1d143faf9 --- /dev/null +++ b/openbis_ng_ui/srcTest/js/components/types/objectType/ObjectTypeHandlerValidate.test.js @@ -0,0 +1,255 @@ +import ObjectTypeHandlerValidate from '../../../../../src/js/components/types/objectType/ObjectTypeHandlerValidate.js' +import ComponentState from '../../../common/ComponentState.js' +import { dto } from '../../../../../src/js/services/openbis.js' + +jest.mock('../../../../../src/js/services/openbis.js') + +beforeEach(() => { + jest.resetAllMocks() + dto.DataType.CONTROLLEDVOCABULARY = 'CONTROLLEDVOCABULARY' + dto.DataType.MATERIAL = 'MATERIAL' +}) + +describe('ObjectTypeHandlerValidateTest', () => { + test('validation enabled with autofocus fails', done => { + const componentState = new ComponentState({ + validate: false, + selection: { + type: 'testtype' + }, + type: { usages: 1 }, + properties: [ + { id: 'property-0' }, + { id: 'property-1', dataType: dto.DataType.CONTROLLEDVOCABULARY }, + { id: 'property-2', dataType: dto.DataType.MATERIAL }, + { id: 'property-3', mandatory: true } + ] + }) + + execute(componentState, true, true).then(result => { + componentState.assertState({ + validate: true, + selection: { + type: 'type', + params: { + part: 'code' + } + }, + type: { + usages: 1, + errors: { + code: 'Code cannot be empty', + generatedCodePrefix: 'Generated code prefix cannot be empty' + } + }, + properties: [ + { + id: 'property-0', + errors: { + code: 'Code cannot be empty', + dataType: 'Data Type cannot be empty', + description: 'Description cannot be empty', + label: 'Label cannot be empty' + } + }, + { + id: 'property-1', + dataType: dto.DataType.CONTROLLEDVOCABULARY, + errors: { + code: 'Code cannot be empty', + description: 'Description cannot be empty', + label: 'Label cannot be empty', + vocabulary: 'Vocabulary cannot be empty' + } + }, + { + id: 'property-2', + dataType: dto.DataType.MATERIAL, + errors: { + code: 'Code cannot be empty', + description: 'Description cannot be empty', + label: 'Label cannot be empty', + materialType: 'Material Type cannot be empty' + } + }, + { + id: 'property-3', + mandatory: true, + errors: { + code: 'Code cannot be empty', + dataType: 'Data Type cannot be empty', + description: 'Description cannot be empty', + label: 'Label cannot be empty', + initialValueForExistingEntities: 'Initial Value cannot be empty' + } + } + ] + }) + expect(result).toBe(false) + done() + }) + }) + + test('validation enabled without autofocus fails', done => { + const componentState = new ComponentState({ + validate: false, + selection: { + type: 'testtype' + }, + type: {}, + properties: [{ id: 'property-0' }] + }) + + execute(componentState, true, false).then(result => { + componentState.assertState({ + validate: true, + selection: { + type: 'testtype' + }, + type: { + errors: { + code: 'Code cannot be empty', + generatedCodePrefix: 'Generated code prefix cannot be empty' + } + }, + properties: [ + { + id: 'property-0', + errors: { + code: 'Code cannot be empty', + dataType: 'Data Type cannot be empty', + description: 'Description cannot be empty', + label: 'Label cannot be empty' + } + } + ] + }) + expect(result).toBe(false) + done() + }) + }) + + test('validation enabled with autofocus succeeds', done => { + const componentState = new ComponentState({ + validate: false, + selection: { + type: 'testtype' + }, + type: { code: 'TYPE_CODE', generatedCodePrefix: 'TYPE_CODE_PREFIX' }, + properties: [ + { + id: 'property-0', + code: 'PROPERTY_CODE', + dataType: 'PROPERTY_DATA_TYPE', + description: 'PROPERTY_DESCRIPTION', + label: 'PROPERTY_LABEL' + } + ] + }) + + execute(componentState, true, true).then(result => { + componentState.assertState({ + validate: true, + selection: { + type: 'testtype' + }, + type: { + code: 'TYPE_CODE', + generatedCodePrefix: 'TYPE_CODE_PREFIX', + errors: {} + }, + properties: [ + { + id: 'property-0', + code: 'PROPERTY_CODE', + dataType: 'PROPERTY_DATA_TYPE', + description: 'PROPERTY_DESCRIPTION', + label: 'PROPERTY_LABEL', + errors: {} + } + ] + }) + expect(result).toBe(true) + done() + }) + }) + + test('validation enabled without autofocus succeeds', done => { + const componentState = new ComponentState({ + validate: false, + selection: { + type: 'testtype' + }, + type: { code: 'TYPE_CODE', generatedCodePrefix: 'TYPE_CODE_PREFIX' }, + properties: [ + { + id: 'property-0', + code: 'PROPERTY_CODE', + dataType: 'PROPERTY_DATA_TYPE', + description: 'PROPERTY_DESCRIPTION', + label: 'PROPERTY_LABEL' + } + ] + }) + + execute(componentState, true, false).then(result => { + componentState.assertState({ + validate: true, + selection: { + type: 'testtype' + }, + type: { + code: 'TYPE_CODE', + generatedCodePrefix: 'TYPE_CODE_PREFIX', + errors: {} + }, + properties: [ + { + id: 'property-0', + code: 'PROPERTY_CODE', + dataType: 'PROPERTY_DATA_TYPE', + description: 'PROPERTY_DESCRIPTION', + label: 'PROPERTY_LABEL', + errors: {} + } + ] + }) + expect(result).toBe(true) + done() + }) + }) + + test('validation disabled', done => { + const componentState = new ComponentState({ + validate: false, + selection: { + type: 'testtype' + }, + type: {}, + properties: [{ id: 'property-0' }] + }) + + execute(componentState, false, true).then(result => { + componentState.assertState({ + validate: false, + selection: { + type: 'testtype' + }, + type: {}, + properties: [{ id: 'property-0' }] + }) + expect(result).toBe(true) + done() + }) + }) +}) + +const execute = (componentState, enabled, autofocus) => { + const handler = new ObjectTypeHandlerValidate( + componentState.getGetState(), + componentState.getSetState() + ) + return handler.setEnabled(enabled).then(() => { + return handler.execute(autofocus) + }) +} -- GitLab