diff options
Diffstat (limited to 'spec/frontend/terraform/components/states_table_actions_spec.js')
-rw-r--r-- | spec/frontend/terraform/components/states_table_actions_spec.js | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/spec/frontend/terraform/components/states_table_actions_spec.js b/spec/frontend/terraform/components/states_table_actions_spec.js new file mode 100644 index 00000000000..264f4b7939a --- /dev/null +++ b/spec/frontend/terraform/components/states_table_actions_spec.js @@ -0,0 +1,189 @@ +import { GlDropdown, GlModal, GlSprintf } from '@gitlab/ui'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import createMockApollo from 'jest/helpers/mock_apollo_helper'; +import VueApollo from 'vue-apollo'; +import StateActions from '~/terraform/components/states_table_actions.vue'; +import lockStateMutation from '~/terraform/graphql/mutations/lock_state.mutation.graphql'; +import removeStateMutation from '~/terraform/graphql/mutations/remove_state.mutation.graphql'; +import unlockStateMutation from '~/terraform/graphql/mutations/unlock_state.mutation.graphql'; + +const localVue = createLocalVue(); +localVue.use(VueApollo); + +describe('StatesTableActions', () => { + let lockResponse; + let removeResponse; + let unlockResponse; + let wrapper; + + const defaultProps = { + state: { + id: 'gid/1', + name: 'state-1', + latestVersion: { downloadPath: '/path' }, + lockedAt: '2020-10-13T00:00:00Z', + }, + }; + + const createMockApolloProvider = () => { + lockResponse = jest.fn().mockResolvedValue({ data: { terraformStateLock: { errors: [] } } }); + + removeResponse = jest + .fn() + .mockResolvedValue({ data: { terraformStateDelete: { errors: [] } } }); + + unlockResponse = jest + .fn() + .mockResolvedValue({ data: { terraformStateUnlock: { errors: [] } } }); + + return createMockApollo([ + [lockStateMutation, lockResponse], + [removeStateMutation, removeResponse], + [unlockStateMutation, unlockResponse], + ]); + }; + + const createComponent = (propsData = defaultProps) => { + const apolloProvider = createMockApolloProvider(); + + wrapper = shallowMount(StateActions, { + apolloProvider, + localVue, + propsData, + stubs: { GlDropdown, GlModal, GlSprintf }, + }); + + return wrapper.vm.$nextTick(); + }; + + const findLockBtn = () => wrapper.find('[data-testid="terraform-state-lock"]'); + const findUnlockBtn = () => wrapper.find('[data-testid="terraform-state-unlock"]'); + const findDownloadBtn = () => wrapper.find('[data-testid="terraform-state-download"]'); + const findRemoveBtn = () => wrapper.find('[data-testid="terraform-state-remove"]'); + const findRemoveModal = () => wrapper.find(GlModal); + + beforeEach(() => { + return createComponent(); + }); + + afterEach(() => { + lockResponse = null; + removeResponse = null; + unlockResponse = null; + wrapper.destroy(); + }); + + describe('download button', () => { + it('displays a download button', () => { + expect(findDownloadBtn().text()).toBe('Download JSON'); + }); + + describe('when state does not have a latestVersion', () => { + beforeEach(() => { + return createComponent({ + state: { + id: 'gid/1', + name: 'state-1', + latestVersion: null, + }, + }); + }); + + it('does not display a download button', () => { + expect(findDownloadBtn().exists()).toBe(false); + }); + }); + }); + + describe('unlock button', () => { + it('displays an unlock button', () => { + expect(findUnlockBtn().text()).toBe('Unlock'); + expect(findLockBtn().exists()).toBe(false); + }); + + describe('when clicking the unlock button', () => { + beforeEach(() => { + findUnlockBtn().vm.$emit('click'); + return wrapper.vm.$nextTick(); + }); + + it('calls the unlock mutation', () => { + expect(unlockResponse).toHaveBeenCalledWith({ + stateID: defaultProps.state.id, + }); + }); + }); + }); + + describe('lock button', () => { + const unlockedProps = { + state: { + id: 'gid/2', + name: 'state-2', + latestVersion: null, + lockedAt: null, + }, + }; + + beforeEach(() => { + return createComponent(unlockedProps); + }); + + it('displays a lock button', () => { + expect(findLockBtn().text()).toBe('Lock'); + expect(findUnlockBtn().exists()).toBe(false); + }); + + describe('when clicking the lock button', () => { + beforeEach(() => { + findLockBtn().vm.$emit('click'); + return wrapper.vm.$nextTick(); + }); + + it('calls the lock mutation', () => { + expect(lockResponse).toHaveBeenCalledWith({ + stateID: unlockedProps.state.id, + }); + }); + }); + }); + + describe('remove button', () => { + it('displays a remove button', () => { + expect(findRemoveBtn().text()).toBe(StateActions.i18n.remove); + }); + + describe('when clicking the remove button', () => { + beforeEach(() => { + findRemoveBtn().vm.$emit('click'); + return wrapper.vm.$nextTick(); + }); + + it('displays a remove modal', () => { + expect(findRemoveModal().text()).toContain( + `You are about to remove the State file ${defaultProps.state.name}`, + ); + }); + + describe('when submitting the remove modal', () => { + it('does not call the remove mutation when state name is missing', async () => { + findRemoveModal().vm.$emit('ok'); + await wrapper.vm.$nextTick(); + + expect(removeResponse).not.toHaveBeenCalledWith(); + }); + + it('calls the remove mutation when state name is present', async () => { + await wrapper.setData({ removeConfirmText: defaultProps.state.name }); + + findRemoveModal().vm.$emit('ok'); + await wrapper.vm.$nextTick(); + + expect(removeResponse).toHaveBeenCalledWith({ + stateID: defaultProps.state.id, + }); + }); + }); + }); + }); +}); |