From 9f46488805e86b1bc341ea1620b866016c2ce5ed Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 20 May 2020 14:34:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-0-stable-ee --- .../clusters/components/applications_spec.js | 33 ++++ .../components/fluentd_output_settings_spec.js | 186 +++++++++++++++++++++ .../components/knative_domain_editor_spec.js | 2 +- spec/frontend/clusters/services/mock_data.js | 1 + .../clusters/stores/clusters_store_spec.js | 18 ++ 5 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 spec/frontend/clusters/components/fluentd_output_settings_spec.js (limited to 'spec/frontend/clusters') diff --git a/spec/frontend/clusters/components/applications_spec.js b/spec/frontend/clusters/components/applications_spec.js index 782e5215ad8..33b30891d5e 100644 --- a/spec/frontend/clusters/components/applications_spec.js +++ b/spec/frontend/clusters/components/applications_spec.js @@ -8,6 +8,7 @@ import eventHub from '~/clusters/event_hub'; import KnativeDomainEditor from '~/clusters/components/knative_domain_editor.vue'; import CrossplaneProviderStack from '~/clusters/components/crossplane_provider_stack.vue'; import IngressModsecuritySettings from '~/clusters/components/ingress_modsecurity_settings.vue'; +import FluentdOutputSettings from '~/clusters/components/fluentd_output_settings.vue'; describe('Applications', () => { let vm; @@ -67,6 +68,10 @@ describe('Applications', () => { it('renders a row for Elastic Stack', () => { expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack')).not.toBeNull(); }); + + it('renders a row for Fluentd', () => { + expect(vm.$el.querySelector('.js-cluster-application-row-fluentd')).not.toBeNull(); + }); }); describe('Group cluster applications', () => { @@ -112,6 +117,10 @@ describe('Applications', () => { it('renders a row for Elastic Stack', () => { expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack')).not.toBeNull(); }); + + it('renders a row for Fluentd', () => { + expect(vm.$el.querySelector('.js-cluster-application-row-fluentd')).not.toBeNull(); + }); }); describe('Instance cluster applications', () => { @@ -157,6 +166,10 @@ describe('Applications', () => { it('renders a row for Elastic Stack', () => { expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack')).not.toBeNull(); }); + + it('renders a row for Fluentd', () => { + expect(vm.$el.querySelector('.js-cluster-application-row-fluentd')).not.toBeNull(); + }); }); describe('Helm application', () => { @@ -240,6 +253,7 @@ describe('Applications', () => { jupyter: { title: 'JupyterHub', hostname: '' }, knative: { title: 'Knative', hostname: '' }, elastic_stack: { title: 'Elastic Stack' }, + fluentd: { title: 'Fluentd' }, }, }); @@ -539,4 +553,23 @@ describe('Applications', () => { }); }); }); + + describe('Fluentd application', () => { + const propsData = { + applications: { + ...APPLICATIONS_MOCK_STATE, + }, + }; + + let wrapper; + beforeEach(() => { + wrapper = shallowMount(Applications, { propsData }); + }); + afterEach(() => { + wrapper.destroy(); + }); + it('renders the correct Component', () => { + expect(wrapper.contains(FluentdOutputSettings)).toBe(true); + }); + }); }); diff --git a/spec/frontend/clusters/components/fluentd_output_settings_spec.js b/spec/frontend/clusters/components/fluentd_output_settings_spec.js new file mode 100644 index 00000000000..5e27cc49049 --- /dev/null +++ b/spec/frontend/clusters/components/fluentd_output_settings_spec.js @@ -0,0 +1,186 @@ +import { shallowMount } from '@vue/test-utils'; +import FluentdOutputSettings from '~/clusters/components/fluentd_output_settings.vue'; +import { APPLICATION_STATUS, FLUENTD } from '~/clusters/constants'; +import { GlAlert, GlDropdown, GlFormCheckbox } from '@gitlab/ui'; +import eventHub from '~/clusters/event_hub'; + +const { UPDATING } = APPLICATION_STATUS; + +describe('FluentdOutputSettings', () => { + let wrapper; + + const defaultSettings = { + protocol: 'tcp', + host: '127.0.0.1', + port: 514, + wafLogEnabled: true, + ciliumLogEnabled: false, + }; + const defaultProps = { + status: 'installable', + updateFailed: false, + ...defaultSettings, + }; + + const createComponent = (props = {}) => { + wrapper = shallowMount(FluentdOutputSettings, { + propsData: { + ...defaultProps, + ...props, + }, + }); + }; + const updateComponentPropsFromEvent = () => { + const { isEditingSettings, ...props } = eventHub.$emit.mock.calls[0][1]; + wrapper.setProps(props); + }; + const findSaveButton = () => wrapper.find({ ref: 'saveBtn' }); + const findCancelButton = () => wrapper.find({ ref: 'cancelBtn' }); + const findProtocolDropdown = () => wrapper.find(GlDropdown); + const findCheckbox = name => + wrapper.findAll(GlFormCheckbox).wrappers.find(x => x.text() === name); + const findHost = () => wrapper.find('#fluentd-host'); + const findPort = () => wrapper.find('#fluentd-port'); + const changeCheckbox = checkbox => { + const currentValue = checkbox.attributes('checked')?.toString() === 'true'; + checkbox.vm.$emit('input', !currentValue); + }; + const changeInput = ({ element }, val) => { + element.value = val; + element.dispatchEvent(new Event('input')); + }; + const changePort = val => changeInput(findPort(), val); + const changeHost = val => changeInput(findHost(), val); + const changeProtocol = idx => findProtocolDropdown().vm.$children[idx].$emit('click'); + const toApplicationSettings = ({ wafLogEnabled, ciliumLogEnabled, ...settings }) => ({ + ...settings, + waf_log_enabled: wafLogEnabled, + cilium_log_enabled: ciliumLogEnabled, + }); + + describe('when fluentd is installed', () => { + beforeEach(() => { + createComponent({ status: 'installed' }); + jest.spyOn(eventHub, '$emit'); + }); + + it('does not render save and cancel buttons', () => { + expect(findSaveButton().exists()).toBe(false); + expect(findCancelButton().exists()).toBe(false); + }); + + describe.each` + desc | changeFn | key | value + ${'when protocol dropdown is triggered'} | ${() => changeProtocol(1)} | ${'protocol'} | ${'udp'} + ${'when host is changed'} | ${() => changeHost('test-host')} | ${'host'} | ${'test-host'} + ${'when port is changed'} | ${() => changePort(123)} | ${'port'} | ${123} + ${'when wafLogEnabled changes'} | ${() => changeCheckbox(findCheckbox('Send ModSecurity Logs'))} | ${'wafLogEnabled'} | ${!defaultSettings.wafLogEnabled} + ${'when ciliumLogEnabled changes'} | ${() => changeCheckbox(findCheckbox('Send Cilium Logs'))} | ${'ciliumLogEnabled'} | ${!defaultSettings.ciliumLogEnabled} + `('$desc', ({ changeFn, key, value }) => { + beforeEach(() => { + changeFn(); + }); + + it('triggers set event to be propagated with the current value', () => { + expect(eventHub.$emit).toHaveBeenCalledWith('setFluentdSettings', { + [key]: value, + isEditingSettings: true, + }); + }); + + describe('when value is updated from store', () => { + beforeEach(() => { + updateComponentPropsFromEvent(); + }); + + it('enables save and cancel buttons', () => { + expect(findSaveButton().exists()).toBe(true); + expect(findSaveButton().attributes().disabled).toBeUndefined(); + expect(findCancelButton().exists()).toBe(true); + expect(findCancelButton().attributes().disabled).toBeUndefined(); + }); + + describe('and the save changes button is clicked', () => { + beforeEach(() => { + eventHub.$emit.mockClear(); + findSaveButton().vm.$emit('click'); + }); + + it('triggers save event and pass current values', () => { + expect(eventHub.$emit).toHaveBeenCalledWith('updateApplication', { + id: FLUENTD, + params: toApplicationSettings({ + ...defaultSettings, + [key]: value, + }), + }); + }); + }); + + describe('and the cancel button is clicked', () => { + beforeEach(() => { + eventHub.$emit.mockClear(); + findCancelButton().vm.$emit('click'); + }); + + it('triggers reset event', () => { + expect(eventHub.$emit).toHaveBeenCalledWith('setFluentdSettings', { + ...defaultSettings, + isEditingSettings: false, + }); + }); + + describe('when value is updated from store', () => { + beforeEach(() => { + updateComponentPropsFromEvent(); + }); + + it('does not render save and cancel buttons', () => { + expect(findSaveButton().exists()).toBe(false); + expect(findCancelButton().exists()).toBe(false); + }); + }); + }); + }); + }); + + describe(`when fluentd status is ${UPDATING}`, () => { + beforeEach(() => { + createComponent({ installed: true, status: UPDATING }); + }); + + it('renders loading spinner in save button', () => { + expect(findSaveButton().props('loading')).toBe(true); + }); + + it('renders disabled save button', () => { + expect(findSaveButton().props('disabled')).toBe(true); + }); + + it('renders save button with "Saving" label', () => { + expect(findSaveButton().text()).toBe('Saving'); + }); + }); + + describe('when fluentd fails to update', () => { + beforeEach(() => { + createComponent({ updateFailed: true }); + }); + + it('displays a error message', () => { + expect(wrapper.contains(GlAlert)).toBe(true); + }); + }); + }); + + describe('when fluentd is not installed', () => { + beforeEach(() => { + createComponent(); + }); + + it('does not render the save button', () => { + expect(findSaveButton().exists()).toBe(false); + expect(findCancelButton().exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/clusters/components/knative_domain_editor_spec.js b/spec/frontend/clusters/components/knative_domain_editor_spec.js index 2de04f7da1f..73d08661199 100644 --- a/spec/frontend/clusters/components/knative_domain_editor_spec.js +++ b/spec/frontend/clusters/components/knative_domain_editor_spec.js @@ -93,7 +93,7 @@ describe('KnativeDomainEditor', () => { it('displays toast indicating a successful update', () => { wrapper.vm.$toast = { show: jest.fn() }; - wrapper.setProps({ knative: Object.assign({ updateSuccessful: true }, knative) }); + wrapper.setProps({ knative: { updateSuccessful: true, ...knative } }); return wrapper.vm.$nextTick(() => { expect(wrapper.vm.$toast.show).toHaveBeenCalledWith( diff --git a/spec/frontend/clusters/services/mock_data.js b/spec/frontend/clusters/services/mock_data.js index 52d78ea1176..c5ec3f6e6a8 100644 --- a/spec/frontend/clusters/services/mock_data.js +++ b/spec/frontend/clusters/services/mock_data.js @@ -159,6 +159,7 @@ const APPLICATIONS_MOCK_STATE = { jupyter: { title: 'JupyterHub', status: 'installable', hostname: '' }, knative: { title: 'Knative ', status: 'installable', hostname: '' }, elastic_stack: { title: 'Elastic Stack', status: 'installable' }, + fluentd: { title: 'Fluentd', status: 'installable' }, }; export { CLUSTERS_MOCK_DATA, DEFAULT_APPLICATION_STATE, APPLICATIONS_MOCK_STATE }; diff --git a/spec/frontend/clusters/stores/clusters_store_spec.js b/spec/frontend/clusters/stores/clusters_store_spec.js index 9fafc688af9..36e99c37be5 100644 --- a/spec/frontend/clusters/stores/clusters_store_spec.js +++ b/spec/frontend/clusters/stores/clusters_store_spec.js @@ -121,6 +121,24 @@ describe('Clusters Store', () => { uninstallFailed: false, validationError: null, }, + fluentd: { + title: 'Fluentd', + status: null, + statusReason: null, + requestReason: null, + port: null, + ciliumLogEnabled: null, + host: null, + protocol: null, + installed: false, + isEditingSettings: false, + installFailed: false, + uninstallable: false, + uninstallSuccessful: false, + uninstallFailed: false, + validationError: null, + wafLogEnabled: null, + }, jupyter: { title: 'JupyterHub', status: mockResponseData.applications[4].status, -- cgit v1.2.3