Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/terraform')
-rw-r--r--spec/frontend/terraform/components/states_table_actions_spec.js181
-rw-r--r--spec/frontend/terraform/components/states_table_spec.js56
-rw-r--r--spec/frontend/terraform/components/terraform_list_spec.js41
3 files changed, 240 insertions, 38 deletions
diff --git a/spec/frontend/terraform/components/states_table_actions_spec.js b/spec/frontend/terraform/components/states_table_actions_spec.js
index 3f5df8a96f8..61f6e9f0f7b 100644
--- a/spec/frontend/terraform/components/states_table_actions_spec.js
+++ b/spec/frontend/terraform/components/states_table_actions_spec.js
@@ -1,7 +1,8 @@
import { GlDropdown, GlModal, GlSprintf } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
-import createMockApollo from 'helpers/mock_apollo_helper';
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';
@@ -13,7 +14,9 @@ localVue.use(VueApollo);
describe('StatesTableActions', () => {
let lockResponse;
let removeResponse;
+ let toast;
let unlockResponse;
+ let updateStateResponse;
let wrapper;
const defaultProps = {
@@ -26,7 +29,9 @@ describe('StatesTableActions', () => {
};
const createMockApolloProvider = () => {
- lockResponse = jest.fn().mockResolvedValue({ data: { terraformStateLock: { errors: [] } } });
+ lockResponse = jest
+ .fn()
+ .mockResolvedValue({ data: { terraformStateLock: { errors: ['There was an error'] } } });
removeResponse = jest
.fn()
@@ -36,26 +41,39 @@ describe('StatesTableActions', () => {
.fn()
.mockResolvedValue({ data: { terraformStateUnlock: { errors: [] } } });
- return createMockApollo([
- [lockStateMutation, lockResponse],
- [removeStateMutation, removeResponse],
- [unlockStateMutation, unlockResponse],
- ]);
+ 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"]');
@@ -69,10 +87,44 @@ describe('StatesTableActions', () => {
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');
@@ -104,7 +156,8 @@ describe('StatesTableActions', () => {
describe('when clicking the unlock button', () => {
beforeEach(() => {
findUnlockBtn().vm.$emit('click');
- return wrapper.vm.$nextTick();
+
+ return waitForPromises();
});
it('calls the unlock mutation', () => {
@@ -137,7 +190,8 @@ describe('StatesTableActions', () => {
describe('when clicking the lock button', () => {
beforeEach(() => {
findLockBtn().vm.$emit('click');
- return wrapper.vm.$nextTick();
+
+ return waitForPromises();
});
it('calls the lock mutation', () => {
@@ -145,6 +199,44 @@ describe('StatesTableActions', () => {
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),
+ );
+ });
});
});
@@ -156,7 +248,7 @@ describe('StatesTableActions', () => {
describe('when clicking the remove button', () => {
beforeEach(() => {
findRemoveBtn().vm.$emit('click');
- return wrapper.vm.$nextTick();
+ return waitForPromises();
});
it('displays a remove modal', () => {
@@ -166,21 +258,70 @@ describe('StatesTableActions', () => {
});
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();
+ describe('when state name is missing', () => {
+ beforeEach(() => {
+ findRemoveModal().vm.$emit('ok');
+ return waitForPromises();
+ });
- expect(removeResponse).not.toHaveBeenCalledWith();
+ it('does not call the remove mutation', () => {
+ expect(removeResponse).not.toHaveBeenCalledWith();
+ });
});
- it('calls the remove mutation when state name is present', async () => {
- await wrapper.setData({ removeConfirmText: defaultProps.state.name });
+ describe('when state name is present', () => {
+ beforeEach(async () => {
+ await wrapper.setData({ removeConfirmText: defaultProps.state.name });
+
+ findRemoveModal().vm.$emit('ok');
- findRemoveModal().vm.$emit('ok');
- await wrapper.vm.$nextTick();
+ 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`);
+ });
- expect(removeResponse).toHaveBeenCalledWith({
- stateID: defaultProps.state.id,
+ 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),
+ );
});
});
});
diff --git a/spec/frontend/terraform/components/states_table_spec.js b/spec/frontend/terraform/components/states_table_spec.js
index f2b7bc00e5b..100e577f514 100644
--- a/spec/frontend/terraform/components/states_table_spec.js
+++ b/spec/frontend/terraform/components/states_table_spec.js
@@ -1,8 +1,8 @@
-import { GlIcon, GlTooltip } from '@gitlab/ui';
+import { GlIcon, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { useFakeDate } from 'helpers/fake_date';
-import StateActions from '~/terraform/components/states_table_actions.vue';
import StatesTable from '~/terraform/components/states_table.vue';
+import StateActions from '~/terraform/components/states_table_actions.vue';
describe('StatesTable', () => {
let wrapper;
@@ -11,7 +11,11 @@ describe('StatesTable', () => {
const defaultProps = {
states: [
{
+ _showDetails: true,
+ errorMessages: ['State 1 has errored'],
name: 'state-1',
+ loadingLock: false,
+ loadingRemove: false,
lockedAt: '2020-10-13T00:00:00Z',
lockedByUser: {
name: 'user-1',
@@ -20,14 +24,22 @@ describe('StatesTable', () => {
latestVersion: null,
},
{
+ _showDetails: false,
+ errorMessages: [],
name: 'state-2',
+ loadingLock: true,
+ loadingRemove: false,
lockedAt: null,
lockedByUser: null,
updatedAt: '2020-10-10T00:00:00Z',
latestVersion: null,
},
{
+ _showDetails: false,
+ errorMessages: [],
name: 'state-3',
+ loadingLock: true,
+ loadingRemove: false,
lockedAt: '2020-10-10T00:00:00Z',
lockedByUser: {
name: 'user-2',
@@ -54,7 +66,11 @@ describe('StatesTable', () => {
},
},
{
+ _showDetails: true,
+ errorMessages: ['State 4 has errored'],
name: 'state-4',
+ loadingLock: false,
+ loadingRemove: false,
lockedAt: '2020-10-10T00:00:00Z',
lockedByUser: null,
updatedAt: '2020-10-10T00:00:00Z',
@@ -76,6 +92,17 @@ describe('StatesTable', () => {
},
},
},
+ {
+ _showDetails: false,
+ errorMessages: [],
+ name: 'state-5',
+ loadingLock: false,
+ loadingRemove: true,
+ lockedAt: null,
+ lockedByUser: null,
+ updatedAt: '2020-10-10T00:00:00Z',
+ latestVersion: null,
+ },
],
};
@@ -96,14 +123,15 @@ describe('StatesTable', () => {
});
it.each`
- name | toolTipText | locked | lineNumber
- ${'state-1'} | ${'Locked by user-1 2 days ago'} | ${true} | ${0}
- ${'state-2'} | ${null} | ${false} | ${1}
- ${'state-3'} | ${'Locked by user-2 5 days ago'} | ${true} | ${2}
- ${'state-4'} | ${'Locked by Unknown User 5 days ago'} | ${true} | ${3}
+ name | toolTipText | locked | loading | lineNumber
+ ${'state-1'} | ${'Locked by user-1 2 days ago'} | ${true} | ${false} | ${0}
+ ${'state-2'} | ${'Locking state'} | ${false} | ${true} | ${1}
+ ${'state-3'} | ${'Unlocking state'} | ${false} | ${true} | ${2}
+ ${'state-4'} | ${'Locked by Unknown User 5 days ago'} | ${true} | ${false} | ${3}
+ ${'state-5'} | ${'Removing'} | ${false} | ${true} | ${4}
`(
'displays the name and locked information "$name" for line "$lineNumber"',
- ({ name, toolTipText, locked, lineNumber }) => {
+ ({ name, toolTipText, locked, loading, lineNumber }) => {
const states = wrapper.findAll('[data-testid="terraform-states-table-name"]');
const state = states.at(lineNumber);
@@ -111,6 +139,7 @@ describe('StatesTable', () => {
expect(state.text()).toContain(name);
expect(state.find(GlIcon).exists()).toBe(locked);
+ expect(state.find(GlLoadingIcon).exists()).toBe(loading);
expect(toolTip.exists()).toBe(locked);
if (locked) {
@@ -154,6 +183,17 @@ describe('StatesTable', () => {
expect(findActions().length).toEqual(0);
});
+ it.each`
+ errorMessage | lineNumber
+ ${defaultProps.states[0].errorMessages[0]} | ${0}
+ ${defaultProps.states[3].errorMessages[0]} | ${1}
+ `('displays table error message "$errorMessage"', ({ errorMessage, lineNumber }) => {
+ const states = wrapper.findAll('[data-testid="terraform-states-table-error"]');
+ const state = states.at(lineNumber);
+
+ expect(state.text()).toBe(errorMessage);
+ });
+
describe('when user is a terraform administrator', () => {
beforeEach(() => {
return createComponent({
diff --git a/spec/frontend/terraform/components/terraform_list_spec.js b/spec/frontend/terraform/components/terraform_list_spec.js
index fb56a7135a3..882b7b55b3e 100644
--- a/spec/frontend/terraform/components/terraform_list_spec.js
+++ b/spec/frontend/terraform/components/terraform_list_spec.js
@@ -1,7 +1,8 @@
import { GlAlert, GlBadge, GlKeysetPagination, GlLoadingIcon, GlTab } from '@gitlab/ui';
import { createLocalVue, shallowMount } from '@vue/test-utils';
-import createMockApollo from 'helpers/mock_apollo_helper';
import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
import EmptyState from '~/terraform/components/empty_state.vue';
import StatesTable from '~/terraform/components/states_table.vue';
import TerraformList from '~/terraform/components/terraform_list.vue';
@@ -27,8 +28,20 @@ describe('TerraformList', () => {
},
};
+ const mockResolvers = {
+ TerraformState: {
+ _showDetails: jest.fn().mockResolvedValue(false),
+ errorMessages: jest.fn().mockResolvedValue([]),
+ loadingLock: jest.fn().mockResolvedValue(false),
+ loadingRemove: jest.fn().mockResolvedValue(false),
+ },
+ Mutation: {
+ addDataToTerraformState: jest.fn().mockResolvedValue({}),
+ },
+ };
+
const statsQueryResponse = queryResponse || jest.fn().mockResolvedValue(apolloQueryResponse);
- const apolloProvider = createMockApollo([[getStatesQuery, statsQueryResponse]]);
+ const apolloProvider = createMockApollo([[getStatesQuery, statsQueryResponse]], mockResolvers);
wrapper = shallowMount(TerraformList, {
localVue,
@@ -52,20 +65,28 @@ describe('TerraformList', () => {
describe('when there is a list of terraform states', () => {
const states = [
{
+ _showDetails: false,
+ errorMessages: [],
id: 'gid://gitlab/Terraform::State/1',
name: 'state-1',
+ latestVersion: null,
+ loadingLock: false,
+ loadingRemove: false,
lockedAt: null,
- updatedAt: null,
lockedByUser: null,
- latestVersion: null,
+ updatedAt: null,
},
{
+ _showDetails: false,
+ errorMessages: [],
id: 'gid://gitlab/Terraform::State/2',
name: 'state-2',
+ latestVersion: null,
+ loadingLock: false,
+ loadingRemove: false,
lockedAt: null,
- updatedAt: null,
lockedByUser: null,
- latestVersion: null,
+ updatedAt: null,
},
];
@@ -83,7 +104,7 @@ describe('TerraformList', () => {
},
});
- return wrapper.vm.$nextTick();
+ return waitForPromises();
});
it('displays a states tab and count', () => {
@@ -111,7 +132,7 @@ describe('TerraformList', () => {
},
});
- return wrapper.vm.$nextTick();
+ return waitForPromises();
});
it('renders the states table without pagination buttons', () => {
@@ -131,7 +152,7 @@ describe('TerraformList', () => {
},
});
- return wrapper.vm.$nextTick();
+ return waitForPromises();
});
it('displays a states tab with no count', () => {
@@ -149,7 +170,7 @@ describe('TerraformList', () => {
beforeEach(() => {
createWrapper({ terraformStates: null, queryResponse: jest.fn().mockRejectedValue() });
- return wrapper.vm.$nextTick();
+ return waitForPromises();
});
it('displays an alert message', () => {