331 lines
9.0 KiB
JavaScript
331 lines
9.0 KiB
JavaScript
import { GlDropdown, GlModal, GlSprintf } from '@gitlab/ui';
|
|
import { createLocalVue, shallowMount } from '@vue/test-utils';
|
|
import VueApollo from 'vue-apollo';
|
|
import createMockApollo from 'helpers/mock_apollo_helper';
|
|
import waitForPromises from 'helpers/wait_for_promises';
|
|
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 toast;
|
|
let unlockResponse;
|
|
let updateStateResponse;
|
|
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: ['There was an error'] } } });
|
|
|
|
removeResponse = jest
|
|
.fn()
|
|
.mockResolvedValue({ data: { terraformStateDelete: { errors: [] } } });
|
|
|
|
unlockResponse = jest
|
|
.fn()
|
|
.mockResolvedValue({ data: { terraformStateUnlock: { errors: [] } } });
|
|
|
|
updateStateResponse = jest.fn().mockResolvedValue({});
|
|
|
|
return createMockApollo(
|
|
[
|
|
[lockStateMutation, lockResponse],
|
|
[removeStateMutation, removeResponse],
|
|
[unlockStateMutation, unlockResponse],
|
|
],
|
|
{
|
|
Mutation: {
|
|
addDataToTerraformState: updateStateResponse,
|
|
},
|
|
},
|
|
);
|
|
};
|
|
|
|
const createComponent = (propsData = defaultProps) => {
|
|
const apolloProvider = createMockApolloProvider();
|
|
|
|
toast = jest.fn();
|
|
|
|
wrapper = shallowMount(StateActions, {
|
|
apolloProvider,
|
|
localVue,
|
|
propsData,
|
|
mocks: { $toast: { show: toast } },
|
|
stubs: { GlDropdown, GlModal, GlSprintf },
|
|
});
|
|
|
|
return wrapper.vm.$nextTick();
|
|
};
|
|
|
|
const findActionsDropdown = () => wrapper.find(GlDropdown);
|
|
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;
|
|
toast = null;
|
|
unlockResponse = null;
|
|
updateStateResponse = null;
|
|
wrapper.destroy();
|
|
});
|
|
|
|
describe('when the state is loading', () => {
|
|
describe('when lock/unlock is processing', () => {
|
|
beforeEach(() => {
|
|
return createComponent({
|
|
state: {
|
|
...defaultProps.state,
|
|
loadingLock: true,
|
|
},
|
|
});
|
|
});
|
|
|
|
it('disables the actions dropdown', () => {
|
|
expect(findActionsDropdown().props('disabled')).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('when remove is processing', () => {
|
|
beforeEach(() => {
|
|
return createComponent({
|
|
state: {
|
|
...defaultProps.state,
|
|
loadingRemove: true,
|
|
},
|
|
});
|
|
});
|
|
|
|
it('disables the actions dropdown', () => {
|
|
expect(findActionsDropdown().props('disabled')).toBe(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
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 waitForPromises();
|
|
});
|
|
|
|
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 waitForPromises();
|
|
});
|
|
|
|
it('calls the lock mutation', () => {
|
|
expect(lockResponse).toHaveBeenCalledWith({
|
|
stateID: unlockedProps.state.id,
|
|
});
|
|
});
|
|
|
|
it('calls mutations to set loading and errors', () => {
|
|
// loading update
|
|
expect(updateStateResponse).toHaveBeenNthCalledWith(
|
|
1,
|
|
{},
|
|
{
|
|
terraformState: {
|
|
...unlockedProps.state,
|
|
_showDetails: false,
|
|
errorMessages: [],
|
|
loadingLock: true,
|
|
loadingRemove: false,
|
|
},
|
|
},
|
|
// Apollo fields
|
|
expect.any(Object),
|
|
expect.any(Object),
|
|
);
|
|
|
|
// final update
|
|
expect(updateStateResponse).toHaveBeenNthCalledWith(
|
|
2,
|
|
{},
|
|
{
|
|
terraformState: {
|
|
...unlockedProps.state,
|
|
_showDetails: true,
|
|
errorMessages: ['There was an error'],
|
|
loadingLock: false,
|
|
loadingRemove: false,
|
|
},
|
|
},
|
|
// Apollo fields
|
|
expect.any(Object),
|
|
expect.any(Object),
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
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 waitForPromises();
|
|
});
|
|
|
|
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', () => {
|
|
describe('when state name is missing', () => {
|
|
beforeEach(() => {
|
|
findRemoveModal().vm.$emit('ok');
|
|
return waitForPromises();
|
|
});
|
|
|
|
it('does not call the remove mutation', () => {
|
|
expect(removeResponse).not.toHaveBeenCalledWith();
|
|
});
|
|
});
|
|
|
|
describe('when state name is present', () => {
|
|
beforeEach(async () => {
|
|
await wrapper.setData({ removeConfirmText: defaultProps.state.name });
|
|
|
|
findRemoveModal().vm.$emit('ok');
|
|
|
|
await waitForPromises();
|
|
});
|
|
|
|
it('calls the remove mutation', () => {
|
|
expect(removeResponse).toHaveBeenCalledWith({ stateID: defaultProps.state.id });
|
|
});
|
|
|
|
it('calls the toast action', () => {
|
|
expect(toast).toHaveBeenCalledWith(`${defaultProps.state.name} successfully removed`);
|
|
});
|
|
|
|
it('calls mutations to set loading and errors', () => {
|
|
// loading update
|
|
expect(updateStateResponse).toHaveBeenNthCalledWith(
|
|
1,
|
|
{},
|
|
{
|
|
terraformState: {
|
|
...defaultProps.state,
|
|
_showDetails: false,
|
|
errorMessages: [],
|
|
loadingLock: false,
|
|
loadingRemove: true,
|
|
},
|
|
},
|
|
// Apollo fields
|
|
expect.any(Object),
|
|
expect.any(Object),
|
|
);
|
|
|
|
// final update
|
|
expect(updateStateResponse).toHaveBeenNthCalledWith(
|
|
2,
|
|
{},
|
|
{
|
|
terraformState: {
|
|
...defaultProps.state,
|
|
_showDetails: false,
|
|
errorMessages: [],
|
|
loadingLock: false,
|
|
loadingRemove: false,
|
|
},
|
|
},
|
|
// Apollo fields
|
|
expect.any(Object),
|
|
expect.any(Object),
|
|
);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|