diff --git a/shell/machine-config/__tests__/vmwarevsphere.test.ts b/shell/machine-config/__tests__/vmwarevsphere.test.ts index 93d781a0127..5f12496f042 100644 --- a/shell/machine-config/__tests__/vmwarevsphere.test.ts +++ b/shell/machine-config/__tests__/vmwarevsphere.test.ts @@ -4,13 +4,12 @@ import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive'; describe('component: vmwarevsphere', () => { const defaultGetters = { 'i18n/t': jest.fn().mockImplementation((key: string) => key) }; - const defaultSetup = { + const poolId = 'poolId'; + const baseSetup = { propsData: { - poolId: 'poolId', + poolId, credentialId: 'credentialId', disabled: false, - mode: 'create', - value: { initted: false }, provider: 'vmwarevsphere' }, mocks: { @@ -20,9 +19,25 @@ describe('component: vmwarevsphere', () => { stubs: { CodeMirror: true }, directives: { cleanHtmlDirective } }; + const defaultCreateSetup = { + ...baseSetup, + propsData: { + ...baseSetup.propsData, + mode: 'create', + value: { initted: false }, + } + }; + const defaultEditSetup = { + ...baseSetup, + propsData: { + ...baseSetup.propsData, + mode: 'edit', + value: { initted: false }, + } + }; it('should mount successfully with correct default values', () => { - const wrapper = mount(vmwarevsphere, defaultSetup); + const wrapper = mount(vmwarevsphere, defaultCreateSetup); const dataCenterElement = wrapper.find(`[data-testid="datacenter"]`).element; const resourcePoolElement = wrapper.find(`[data-testid="resourcePool"]`).element; @@ -78,7 +93,7 @@ describe('component: vmwarevsphere', () => { ]; it.each(testCases)('should generate label/value object without manipultion', (rawData, expected) => { - const wrapper = mount(vmwarevsphere, defaultSetup); + const wrapper = mount(vmwarevsphere, defaultCreateSetup); expect(wrapper.vm.mapPathOptionsToContent(rawData)).toStrictEqual(expected); }); @@ -95,7 +110,7 @@ describe('component: vmwarevsphere', () => { ]; it.each(testCases)('should generate label/value object for host options properly', (rawData, expected) => { - const wrapper = mount(vmwarevsphere, defaultSetup); + const wrapper = mount(vmwarevsphere, defaultCreateSetup); expect(wrapper.vm.mapHostOptionsToContent(rawData)).toStrictEqual(expected); }); @@ -114,7 +129,7 @@ describe('component: vmwarevsphere', () => { ]; it.each(testCases)('should generate label/value object for folder options properly', (rawData, expected) => { - const wrapper = mount(vmwarevsphere, defaultSetup); + const wrapper = mount(vmwarevsphere, defaultCreateSetup); expect(wrapper.vm.mapFolderOptionsToContent(rawData)).toStrictEqual(expected); }); @@ -127,7 +142,7 @@ describe('component: vmwarevsphere', () => { ]; it.each(testCases)('should generate label/value object for custom attributes options properly', (rawData, expected) => { - const wrapper = mount(vmwarevsphere, defaultSetup); + const wrapper = mount(vmwarevsphere, defaultCreateSetup); expect(wrapper.vm.mapCustomAttributesToContent(rawData)).toStrictEqual(expected); }); @@ -143,9 +158,71 @@ describe('component: vmwarevsphere', () => { const expectedReslut = [{ ...tag, label: `${ tag.category } / ${ tag.name }`, value: tag.id }]; - const wrapper = mount(vmwarevsphere, defaultSetup); + const wrapper = mount(vmwarevsphere, defaultCreateSetup); expect(wrapper.vm.mapTagsToContent([tag])).toStrictEqual(expectedReslut); }); }); + + describe('resetValueIfNecessary', () => { + const hostsystemOptions = ['', '/Datacenter/host/Cluster/111.11.11.1']; + const folderOptions = ['', '/Datacenter/vm', '/Datacenter/vm/sub-folder']; + + it('should add errors to validationError collection when values are no in the options', () => { + const setup = { + ...defaultEditSetup, + propsData: { + ...defaultEditSetup.propsData, + value: { + ...defaultEditSetup.propsData.value, + hostsystem: 'something that is not included in the options', + folder: 'again, something that is not included in the options' + } + } + }; + + const wrapper = mount(vmwarevsphere, setup); + + const hostsystemContent = wrapper.vm.mapHostOptionsToContent(hostsystemOptions); + + wrapper.vm.resetValueIfNecessary('hostsystem', hostsystemContent, hostsystemOptions); + + const folderContent = wrapper.vm.mapHostOptionsToContent(folderOptions); + + wrapper.vm.resetValueIfNecessary('folder', folderContent, folderOptions); + + expect(wrapper.vm.$data.validationErrors[poolId]).toContain('hostsystem'); + expect(wrapper.vm.$data.validationErrors[poolId]).toContain('folder'); + }); + + describe('hostsystem and folder', () => { + const testCases = [null, '']; + + it.each(testCases)('should NOT be added to validationError collection if they are null or ""', (data) => { + const setup = { + ...defaultEditSetup, + propsData: { + ...defaultEditSetup.propsData, + value: { + ...defaultEditSetup.propsData.value, + hostsystem: data, + folder: data + } + } + }; + + const wrapper = mount(vmwarevsphere, setup); + + const hostsystemContent = wrapper.vm.mapHostOptionsToContent(hostsystemOptions); + + wrapper.vm.resetValueIfNecessary('hostsystem', hostsystemContent, hostsystemOptions); + + const folderContent = wrapper.vm.mapHostOptionsToContent(folderOptions); + + wrapper.vm.resetValueIfNecessary('folder', folderContent, folderOptions); + + expect(wrapper.vm.$data.validationErrors[poolId]).toBeUndefined(); + }); + }); + }); }); diff --git a/shell/machine-config/vmwarevsphere.vue b/shell/machine-config/vmwarevsphere.vue index 34c25fa3600..cb96a08191a 100644 --- a/shell/machine-config/vmwarevsphere.vue +++ b/shell/machine-config/vmwarevsphere.vue @@ -646,15 +646,16 @@ export default { }; if (!isValueInContent()) { - if (this.mode === _CREATE) { - const value = isArray ? [] : content[0]?.value; + const value = isArray ? [] : content[0]?.value; + // null and "" are valid values for hostsystem and folder + const isFolderNullOrEmpty = key === 'folder' && (this.value.folder === null || this.value.folder === ''); + const isHostsystemNullOrEmpty = key === 'hostsystem' && (this.value.hostsystem === null || this.value.hostsystem === ''); - if (value !== SENTINEL) { - set(this.value, key, value); - } + if (this.mode === _CREATE && value !== SENTINEL) { + set(this.value, key, value); } - if ([_EDIT, _VIEW].includes(this.mode)) { + if ([_EDIT, _VIEW].includes(this.mode) && !isFolderNullOrEmpty && !isHostsystemNullOrEmpty) { this.manageErrors(errorActions.CREATE, key); } } else {