diff options
Diffstat (limited to 'spec/frontend/ci_variable_list/components')
4 files changed, 0 insertions, 566 deletions
diff --git a/spec/frontend/ci_variable_list/components/legacy_ci_environments_dropdown_spec.js b/spec/frontend/ci_variable_list/components/legacy_ci_environments_dropdown_spec.js deleted file mode 100644 index b3e23ba4201..00000000000 --- a/spec/frontend/ci_variable_list/components/legacy_ci_environments_dropdown_spec.js +++ /dev/null @@ -1,119 +0,0 @@ -import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; -import Vuex from 'vuex'; -import LegacyCiEnvironmentsDropdown from '~/ci_variable_list/components/legacy_ci_environments_dropdown.vue'; - -Vue.use(Vuex); - -describe('Ci environments dropdown', () => { - let wrapper; - let store; - - const enterSearchTerm = (value) => - wrapper.find('[data-testid="ci-environment-search"]').setValue(value); - - const createComponent = (term) => { - store = new Vuex.Store({ - getters: { - joinedEnvironments: () => ['dev', 'prod', 'staging'], - }, - }); - - wrapper = mount(LegacyCiEnvironmentsDropdown, { - store, - propsData: { - value: term, - }, - }); - enterSearchTerm(term); - }; - - const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); - const findDropdownItemByIndex = (index) => wrapper.findAllComponents(GlDropdownItem).at(index); - const findActiveIconByIndex = (index) => findDropdownItemByIndex(index).findComponent(GlIcon); - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - describe('No environments found', () => { - beforeEach(() => { - createComponent('stable'); - }); - - it('renders create button with search term if environments do not contain search term', () => { - expect(findAllDropdownItems()).toHaveLength(2); - expect(findDropdownItemByIndex(1).text()).toBe('Create wildcard: stable'); - }); - - it('renders empty results message', () => { - expect(findDropdownItemByIndex(0).text()).toBe('No matching results'); - }); - }); - - describe('Search term is empty', () => { - beforeEach(() => { - createComponent(''); - }); - - it('renders all environments when search term is empty', () => { - expect(findAllDropdownItems()).toHaveLength(3); - expect(findDropdownItemByIndex(0).text()).toBe('dev'); - expect(findDropdownItemByIndex(1).text()).toBe('prod'); - expect(findDropdownItemByIndex(2).text()).toBe('staging'); - }); - - it('should not display active checkmark on the inactive stage', () => { - expect(findActiveIconByIndex(0).classes('gl-visibility-hidden')).toBe(true); - }); - }); - - describe('Environments found', () => { - beforeEach(async () => { - createComponent('prod'); - await nextTick(); - }); - - it('renders only the environment searched for', () => { - expect(findAllDropdownItems()).toHaveLength(1); - expect(findDropdownItemByIndex(0).text()).toBe('prod'); - }); - - it('should not display create button', () => { - const environments = findAllDropdownItems().filter((env) => env.text().startsWith('Create')); - expect(environments).toHaveLength(0); - expect(findAllDropdownItems()).toHaveLength(1); - }); - - it('should not display empty results message', () => { - expect(wrapper.findComponent({ ref: 'noMatchingResults' }).exists()).toBe(false); - }); - - it('should display active checkmark if active', () => { - expect(findActiveIconByIndex(0).classes('gl-visibility-hidden')).toBe(false); - }); - - it('should clear the search term when showing the dropdown', () => { - wrapper.findComponent(GlDropdown).trigger('click'); - - expect(wrapper.find('[data-testid="ci-environment-search"]').text()).toBe(''); - }); - - describe('Custom events', () => { - it('should emit selectEnvironment if an environment is clicked', () => { - findDropdownItemByIndex(0).vm.$emit('click'); - expect(wrapper.emitted('selectEnvironment')).toEqual([['prod']]); - }); - - it('should emit createClicked if an environment is clicked', async () => { - createComponent('newscope'); - - await nextTick(); - findDropdownItemByIndex(1).vm.$emit('click'); - expect(wrapper.emitted('createClicked')).toEqual([['newscope']]); - }); - }); - }); -}); diff --git a/spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js b/spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js deleted file mode 100644 index b607232907b..00000000000 --- a/spec/frontend/ci_variable_list/components/legacy_ci_variable_modal_spec.js +++ /dev/null @@ -1,323 +0,0 @@ -import { GlButton, GlFormInput } from '@gitlab/ui'; -import { shallowMount, mount } from '@vue/test-utils'; -import Vue from 'vue'; -import Vuex from 'vuex'; -import { mockTracking } from 'helpers/tracking_helper'; -import CiEnvironmentsDropdown from '~/ci_variable_list/components/ci_environments_dropdown.vue'; -import LegacyCiVariableModal from '~/ci_variable_list/components/legacy_ci_variable_modal.vue'; -import { - AWS_ACCESS_KEY_ID, - EVENT_LABEL, - EVENT_ACTION, - ENVIRONMENT_SCOPE_LINK_TITLE, -} from '~/ci_variable_list/constants'; -import createStore from '~/ci_variable_list/store'; -import mockData from '../services/mock_data'; -import ModalStub from '../stubs'; - -Vue.use(Vuex); - -describe('Ci variable modal', () => { - let wrapper; - let store; - let trackingSpy; - - const maskableRegex = '^[a-zA-Z0-9_+=/@:.~-]{8,}$'; - - const createComponent = (method, options = {}) => { - store = createStore({ - maskableRegex, - isGroup: options.isGroup, - environmentScopeLink: '/help/environments', - }); - wrapper = method(LegacyCiVariableModal, { - attachTo: document.body, - stubs: { - GlModal: ModalStub, - }, - store, - ...options, - }); - }; - - const findCiEnvironmentsDropdown = () => wrapper.findComponent(CiEnvironmentsDropdown); - const findModal = () => wrapper.findComponent(ModalStub); - const findAddorUpdateButton = () => findModal().find('[data-testid="ciUpdateOrAddVariableBtn"]'); - const deleteVariableButton = () => - findModal() - .findAllComponents(GlButton) - .wrappers.find((button) => button.props('variant') === 'danger'); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('Basic interactions', () => { - beforeEach(() => { - createComponent(shallowMount); - }); - - it('button is disabled when no key/value pair are present', () => { - expect(findAddorUpdateButton().attributes('disabled')).toBe('true'); - }); - }); - - describe('Adding a new variable', () => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - createComponent(shallowMount); - jest.spyOn(store, 'dispatch').mockImplementation(); - store.state.variable = variable; - }); - - it('button is enabled when key/value pair are present', () => { - expect(findAddorUpdateButton().attributes('disabled')).toBeUndefined(); - }); - - it('Add variable button dispatches addVariable action', () => { - findAddorUpdateButton().vm.$emit('click'); - expect(store.dispatch).toHaveBeenCalledWith('addVariable'); - }); - - it('Clears the modal state once modal is hidden', () => { - findModal().vm.$emit('hidden'); - expect(store.dispatch).toHaveBeenCalledWith('clearModal'); - }); - - it('should dispatch setVariableProtected when admin settings are configured to protect variables', () => { - store.state.isProtectedByDefault = true; - findModal().vm.$emit('shown'); - - expect(store.dispatch).toHaveBeenCalledWith('setVariableProtected'); - }); - }); - - describe('Adding a new non-AWS variable', () => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - const invalidKeyVariable = { - ...variable, - key: 'key', - value: 'value', - secret_value: 'secret_value', - }; - createComponent(mount); - store.state.variable = invalidKeyVariable; - }); - - it('does not show AWS guidance tip', () => { - const tip = wrapper.find(`div[data-testid='aws-guidance-tip']`); - expect(tip.exists()).toBe(true); - expect(tip.isVisible()).toBe(false); - }); - }); - - describe('Adding a new AWS variable', () => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - const invalidKeyVariable = { - ...variable, - key: AWS_ACCESS_KEY_ID, - value: 'AKIAIOSFODNN7EXAMPLEjdhy', - secret_value: 'AKIAIOSFODNN7EXAMPLEjdhy', - }; - createComponent(mount); - store.state.variable = invalidKeyVariable; - }); - - it('shows AWS guidance tip', () => { - const tip = wrapper.find(`[data-testid='aws-guidance-tip']`); - expect(tip.exists()).toBe(true); - expect(tip.isVisible()).toBe(true); - }); - }); - - describe.each` - value | secret | rendered - ${'value'} | ${'secret_value'} | ${false} - ${'dollar$ign'} | ${'dollar$ign'} | ${true} - `('Adding a new variable', ({ value, secret, rendered }) => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - const invalidKeyVariable = { - ...variable, - key: 'key', - value, - secret_value: secret, - }; - createComponent(mount); - store.state.variable = invalidKeyVariable; - trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); - }); - - it(`${rendered ? 'renders' : 'does not render'} the variable reference warning`, () => { - const warning = wrapper.find(`[data-testid='contains-variable-reference']`); - expect(warning.exists()).toBe(rendered); - }); - }); - - describe('Editing a variable', () => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - createComponent(shallowMount); - jest.spyOn(store, 'dispatch').mockImplementation(); - store.state.variableBeingEdited = variable; - }); - - it('button text is Update variable when updating', () => { - expect(findAddorUpdateButton().text()).toBe('Update variable'); - }); - - it('Update variable button dispatches updateVariable with correct variable', () => { - findAddorUpdateButton().vm.$emit('click'); - expect(store.dispatch).toHaveBeenCalledWith('updateVariable'); - }); - - it('Resets the editing state once modal is hidden', () => { - findModal().vm.$emit('hidden'); - expect(store.dispatch).toHaveBeenCalledWith('resetEditing'); - }); - - it('dispatches deleteVariable with correct variable to delete', () => { - deleteVariableButton().vm.$emit('click'); - expect(store.dispatch).toHaveBeenCalledWith('deleteVariable'); - }); - }); - - describe('Environment scope', () => { - describe('group level variables', () => { - it('renders the environment dropdown', () => { - createComponent(shallowMount, { - isGroup: true, - provide: { - glFeatures: { - groupScopedCiVariables: true, - }, - }, - }); - - expect(findCiEnvironmentsDropdown().exists()).toBe(true); - expect(findCiEnvironmentsDropdown().isVisible()).toBe(true); - }); - - describe('licensed feature is not available', () => { - it('disables the dropdown', () => { - createComponent(mount, { - isGroup: true, - provide: { - glFeatures: { - groupScopedCiVariables: false, - }, - }, - }); - - const environmentScopeInput = wrapper - .find('[data-testid="environment-scope"]') - .findComponent(GlFormInput); - expect(findCiEnvironmentsDropdown().exists()).toBe(false); - expect(environmentScopeInput.attributes('readonly')).toBe('readonly'); - }); - }); - }); - - it('renders a link to documentation on scopes', () => { - createComponent(mount); - - const link = wrapper.find('[data-testid="environment-scope-link"]'); - - expect(link.attributes('title')).toBe(ENVIRONMENT_SCOPE_LINK_TITLE); - expect(link.attributes('href')).toBe('/help/environments'); - }); - }); - - describe('Validations', () => { - const maskError = 'This variable can not be masked.'; - - describe('when the mask state is invalid', () => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - const invalidMaskVariable = { - ...variable, - key: 'qs', - value: 'd:;', - secret_value: 'd:;', - masked: true, - }; - createComponent(mount); - store.state.variable = invalidMaskVariable; - trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); - }); - - it('disables the submit button', () => { - expect(findAddorUpdateButton().attributes('disabled')).toBe('disabled'); - }); - - it('shows the correct error text', () => { - expect(findModal().text()).toContain(maskError); - }); - - it('sends the correct tracking event', () => { - expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTION, { - label: EVENT_LABEL, - property: ';', - }); - }); - }); - - describe.each` - value | secret | masked | eventSent | trackingErrorProperty - ${'value'} | ${'secretValue'} | ${false} | ${0} | ${null} - ${'shortMasked'} | ${'short'} | ${true} | ${0} | ${null} - ${'withDollar$Sign'} | ${'dollar$ign'} | ${false} | ${1} | ${'$'} - ${'withDollar$Sign'} | ${'dollar$ign'} | ${true} | ${1} | ${'$'} - ${'unsupported'} | ${'unsupported|char'} | ${true} | ${1} | ${'|'} - ${'unsupportedMasked'} | ${'unsupported|char'} | ${false} | ${0} | ${null} - `('Adding a new variable', ({ value, secret, masked, eventSent, trackingErrorProperty }) => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - const invalidKeyVariable = { - ...variable, - key: 'key', - value, - secret_value: secret, - masked, - }; - createComponent(mount); - store.state.variable = invalidKeyVariable; - trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); - }); - - it(`${ - eventSent > 0 ? 'sends the correct' : 'does not send the' - } variable validation tracking event`, () => { - expect(trackingSpy).toHaveBeenCalledTimes(eventSent); - - if (eventSent > 0) { - expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTION, { - label: EVENT_LABEL, - property: trackingErrorProperty, - }); - } - }); - }); - - describe('when both states are valid', () => { - beforeEach(() => { - const [variable] = mockData.mockVariables; - const validMaskandKeyVariable = { - ...variable, - key: AWS_ACCESS_KEY_ID, - value: '12345678', - secret_value: '87654321', - masked: true, - }; - createComponent(mount); - store.state.variable = validMaskandKeyVariable; - }); - - it('does not disable the submit button', () => { - expect(findAddorUpdateButton().attributes('disabled')).toBeUndefined(); - }); - }); - }); -}); diff --git a/spec/frontend/ci_variable_list/components/legacy_ci_variable_settings_spec.js b/spec/frontend/ci_variable_list/components/legacy_ci_variable_settings_spec.js deleted file mode 100644 index 7def4dd4f29..00000000000 --- a/spec/frontend/ci_variable_list/components/legacy_ci_variable_settings_spec.js +++ /dev/null @@ -1,38 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; -import Vuex from 'vuex'; -import LegacyCiVariableSettings from '~/ci_variable_list/components/legacy_ci_variable_settings.vue'; -import createStore from '~/ci_variable_list/store'; - -Vue.use(Vuex); - -describe('Ci variable table', () => { - let wrapper; - let store; - let isProject; - - const createComponent = (projectState) => { - store = createStore(); - store.state.isProject = projectState; - jest.spyOn(store, 'dispatch').mockImplementation(); - wrapper = shallowMount(LegacyCiVariableSettings, { - store, - }); - }; - - afterEach(() => { - wrapper.destroy(); - }); - - it('dispatches fetchEnvironments when mounted', () => { - isProject = true; - createComponent(isProject); - expect(store.dispatch).toHaveBeenCalledWith('fetchEnvironments'); - }); - - it('does not dispatch fetchenvironments when in group context', () => { - isProject = false; - createComponent(isProject); - expect(store.dispatch).not.toHaveBeenCalled(); - }); -}); diff --git a/spec/frontend/ci_variable_list/components/legacy_ci_variable_table_spec.js b/spec/frontend/ci_variable_list/components/legacy_ci_variable_table_spec.js deleted file mode 100644 index 310afc8003a..00000000000 --- a/spec/frontend/ci_variable_list/components/legacy_ci_variable_table_spec.js +++ /dev/null @@ -1,86 +0,0 @@ -import Vue from 'vue'; -import Vuex from 'vuex'; -import { mountExtended } from 'helpers/vue_test_utils_helper'; -import LegacyCiVariableTable from '~/ci_variable_list/components/legacy_ci_variable_table.vue'; -import createStore from '~/ci_variable_list/store'; -import mockData from '../services/mock_data'; - -Vue.use(Vuex); - -describe('Ci variable table', () => { - let wrapper; - let store; - - const createComponent = () => { - store = createStore(); - jest.spyOn(store, 'dispatch').mockImplementation(); - wrapper = mountExtended(LegacyCiVariableTable, { - attachTo: document.body, - store, - }); - }; - - const findRevealButton = () => wrapper.findByText('Reveal values'); - const findEditButton = () => wrapper.findByLabelText('Edit'); - const findEmptyVariablesPlaceholder = () => wrapper.findByText('There are no variables yet.'); - - beforeEach(() => { - createComponent(); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('dispatches fetchVariables when mounted', () => { - expect(store.dispatch).toHaveBeenCalledWith('fetchVariables'); - }); - - describe('When table is empty', () => { - beforeEach(() => { - store.state.variables = []; - }); - - it('displays empty message', () => { - expect(findEmptyVariablesPlaceholder().exists()).toBe(true); - }); - - it('hides the reveal button', () => { - expect(findRevealButton().exists()).toBe(false); - }); - }); - - describe('When table has variables', () => { - beforeEach(() => { - store.state.variables = mockData.mockVariables; - }); - - it('does not display the empty message', () => { - expect(findEmptyVariablesPlaceholder().exists()).toBe(false); - }); - - it('displays the reveal button', () => { - expect(findRevealButton().exists()).toBe(true); - }); - - it('displays the correct amount of variables', async () => { - expect(wrapper.findAll('.js-ci-variable-row')).toHaveLength(1); - }); - }); - - describe('Table click actions', () => { - beforeEach(() => { - store.state.variables = mockData.mockVariables; - }); - - it('reveals secret values when button is clicked', () => { - findRevealButton().trigger('click'); - expect(store.dispatch).toHaveBeenCalledWith('toggleValues', false); - }); - - it('dispatches editVariable with correct variable to edit', () => { - findEditButton().trigger('click'); - expect(store.dispatch).toHaveBeenCalledWith('editVariable', mockData.mockVariables[0]); - }); - }); -}); |