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/deploy_keys/components/app_spec.js')
-rw-r--r--spec/frontend/deploy_keys/components/app_spec.js244
1 files changed, 193 insertions, 51 deletions
diff --git a/spec/frontend/deploy_keys/components/app_spec.js b/spec/frontend/deploy_keys/components/app_spec.js
index de4112134ce..5e012bc1c51 100644
--- a/spec/frontend/deploy_keys/components/app_spec.js
+++ b/spec/frontend/deploy_keys/components/app_spec.js
@@ -1,28 +1,45 @@
+import VueApollo from 'vue-apollo';
+import Vue, { nextTick } from 'vue';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
-import { nextTick } from 'vue';
-import data from 'test_fixtures/deploy_keys/keys.json';
+import { GlPagination } from '@gitlab/ui';
+import enabledKeys from 'test_fixtures/deploy_keys/enabled_keys.json';
+import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import { TEST_HOST } from 'spec/test_constants';
+import { captureException } from '~/sentry/sentry_browser_wrapper';
+import { mapDeployKey } from '~/deploy_keys/graphql/resolvers';
+import deployKeysQuery from '~/deploy_keys/graphql/queries/deploy_keys.query.graphql';
import deployKeysApp from '~/deploy_keys/components/app.vue';
import ConfirmModal from '~/deploy_keys/components/confirm_modal.vue';
import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
-import eventHub from '~/deploy_keys/eventhub';
import axios from '~/lib/utils/axios_utils';
-import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
-const TEST_ENDPOINT = `${TEST_HOST}/dummy/`;
+jest.mock('~/sentry/sentry_browser_wrapper');
+
+Vue.use(VueApollo);
describe('Deploy keys app component', () => {
let wrapper;
let mock;
+ let deployKeyMock;
+ let currentPageMock;
+ let currentScopeMock;
+ let confirmRemoveKeyMock;
+ let pageInfoMock;
+ let pageMutationMock;
+ let scopeMutationMock;
+ let disableKeyMock;
+ let resolvers;
const mountComponent = () => {
+ const apolloProvider = createMockApollo([[deployKeysQuery, deployKeyMock]], resolvers);
+
wrapper = mount(deployKeysApp, {
propsData: {
- endpoint: TEST_ENDPOINT,
+ projectPath: 'test/project',
projectId: '8',
},
+ apolloProvider,
});
return waitForPromises();
@@ -30,7 +47,28 @@ describe('Deploy keys app component', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
- mock.onGet(TEST_ENDPOINT).reply(HTTP_STATUS_OK, data);
+ deployKeyMock = jest.fn();
+ currentPageMock = jest.fn();
+ currentScopeMock = jest.fn();
+ confirmRemoveKeyMock = jest.fn();
+ pageInfoMock = jest.fn();
+ scopeMutationMock = jest.fn();
+ pageMutationMock = jest.fn();
+ disableKeyMock = jest.fn();
+
+ resolvers = {
+ Query: {
+ currentPage: currentPageMock,
+ currentScope: currentScopeMock,
+ deployKeyToRemove: confirmRemoveKeyMock,
+ pageInfo: pageInfoMock,
+ },
+ Mutation: {
+ currentPage: pageMutationMock,
+ currentScope: scopeMutationMock,
+ disableKey: disableKeyMock,
+ },
+ };
});
afterEach(() => {
@@ -43,8 +81,7 @@ describe('Deploy keys app component', () => {
const findNavigationTabs = () => wrapper.findComponent(NavigationTabs);
it('renders loading icon while waiting for request', async () => {
- mock.onGet(TEST_ENDPOINT).reply(() => new Promise());
-
+ deployKeyMock.mockReturnValue(new Promise(() => {}));
mountComponent();
await nextTick();
@@ -52,85 +89,190 @@ describe('Deploy keys app component', () => {
});
it('renders keys panels', async () => {
+ const deployKeys = enabledKeys.keys.map(mapDeployKey);
+ deployKeyMock.mockReturnValue({
+ data: {
+ project: { id: 1, deployKeys, __typename: 'Project' },
+ },
+ });
await mountComponent();
expect(findKeyPanels().length).toBe(3);
});
- it.each`
- selector
- ${'.js-deployKeys-tab-enabled_keys'}
- ${'.js-deployKeys-tab-available_project_keys'}
- ${'.js-deployKeys-tab-public_keys'}
- `('$selector title exists', ({ selector }) => {
- return mountComponent().then(() => {
+ describe.each`
+ scope
+ ${'enabledKeys'}
+ ${'availableProjectKeys'}
+ ${'availablePublicKeys'}
+ `('tab $scope', ({ scope }) => {
+ let selector;
+
+ beforeEach(async () => {
+ selector = `.js-deployKeys-tab-${scope}`;
+ const deployKeys = enabledKeys.keys.map(mapDeployKey);
+ deployKeyMock.mockReturnValue({
+ data: {
+ project: { id: 1, deployKeys, __typename: 'Project' },
+ },
+ });
+
+ await mountComponent();
+ });
+
+ it('displays the title', () => {
const element = wrapper.find(selector);
expect(element.exists()).toBe(true);
});
+
+ it('triggers changing the scope on click', async () => {
+ await findNavigationTabs().vm.$emit('onChangeTab', scope);
+
+ expect(scopeMutationMock).toHaveBeenCalledWith(
+ expect.anything(),
+ { scope },
+ expect.anything(),
+ expect.anything(),
+ );
+ });
});
- it('does not render key panels when keys object is empty', () => {
- mock.onGet(TEST_ENDPOINT).reply(HTTP_STATUS_OK, []);
+ it('captures a failed tab change', async () => {
+ const scope = 'fake scope';
+ const error = new Error('fail!');
- return mountComponent().then(() => {
- expect(findKeyPanels().length).toBe(0);
+ const deployKeys = enabledKeys.keys.map(mapDeployKey);
+ deployKeyMock.mockReturnValue({
+ data: {
+ project: { id: 1, deployKeys, __typename: 'Project' },
+ },
});
+
+ scopeMutationMock.mockRejectedValue(error);
+ await mountComponent();
+ await findNavigationTabs().vm.$emit('onChangeTab', scope);
+ await waitForPromises();
+
+ expect(captureException).toHaveBeenCalledWith(error, { tags: { deployKeyScope: scope } });
});
it('hasKeys returns true when there are keys', async () => {
+ const deployKeys = enabledKeys.keys.map(mapDeployKey);
+ deployKeyMock.mockReturnValue({
+ data: {
+ project: { id: 1, deployKeys, __typename: 'Project' },
+ },
+ });
await mountComponent();
expect(findNavigationTabs().exists()).toBe(true);
expect(findLoadingIcon().exists()).toBe(false);
});
- describe('enabling and disabling keys', () => {
- const key = data.public_keys[0];
- let getMethodMock;
- let putMethodMock;
+ describe('disabling keys', () => {
+ const key = mapDeployKey(enabledKeys.keys[0]);
+
+ beforeEach(() => {
+ deployKeyMock.mockReturnValue({
+ data: {
+ project: { id: 1, deployKeys: [key], __typename: 'Project' },
+ },
+ });
+ });
- const removeKey = async (keyEvent) => {
- eventHub.$emit(keyEvent, key, () => {});
+ it('re-fetches deploy keys when disabling a key', async () => {
+ confirmRemoveKeyMock.mockReturnValue(key);
+ await mountComponent();
+ expect(deployKeyMock).toHaveBeenCalledTimes(1);
await nextTick();
expect(findModal().props('visible')).toBe(true);
findModal().vm.$emit('remove');
- };
-
- beforeEach(() => {
- getMethodMock = jest.spyOn(axios, 'get');
- putMethodMock = jest.spyOn(axios, 'put');
+ await waitForPromises();
+ expect(deployKeyMock).toHaveBeenCalledTimes(2);
});
+ });
- afterEach(() => {
- getMethodMock.mockClear();
- putMethodMock.mockClear();
- });
+ describe('pagination', () => {
+ const key = mapDeployKey(enabledKeys.keys[0]);
+ let page;
+ let pageInfo;
+ let glPagination;
- it('re-fetches deploy keys when enabling a key', async () => {
- await mountComponent();
+ beforeEach(async () => {
+ page = 2;
+ pageInfo = {
+ total: 20,
+ perPage: 5,
+ nextPage: 3,
+ page,
+ previousPage: 1,
+ __typename: 'LocalPageInfo',
+ };
+ deployKeyMock.mockReturnValue({
+ data: {
+ project: { id: 1, deployKeys: [], __typename: 'Project' },
+ },
+ });
- eventHub.$emit('enable.key', key);
+ confirmRemoveKeyMock.mockReturnValue(key);
+ pageInfoMock.mockReturnValue(pageInfo);
+ currentPageMock.mockReturnValue(page);
+ await mountComponent();
+ glPagination = wrapper.findComponent(GlPagination);
+ });
- expect(putMethodMock).toHaveBeenCalledWith(`${TEST_ENDPOINT}/${key.id}/enable`);
- expect(getMethodMock).toHaveBeenCalled();
+ it('shows pagination with correct page info', () => {
+ expect(glPagination.exists()).toBe(true);
+ expect(glPagination.props()).toMatchObject({
+ totalItems: pageInfo.total,
+ perPage: pageInfo.perPage,
+ value: page,
+ });
});
- it('re-fetches deploy keys when disabling a key', async () => {
- await mountComponent();
+ it('moves back a page', async () => {
+ await glPagination.vm.$emit('previous');
- await removeKey('disable.key');
+ expect(pageMutationMock).toHaveBeenCalledWith(
+ expect.anything(),
+ { page: page - 1 },
+ expect.anything(),
+ expect.anything(),
+ );
+ });
+
+ it('moves forward a page', async () => {
+ await glPagination.vm.$emit('next');
- expect(putMethodMock).toHaveBeenCalledWith(`${TEST_ENDPOINT}/${key.id}/disable`);
- expect(getMethodMock).toHaveBeenCalled();
+ expect(pageMutationMock).toHaveBeenCalledWith(
+ expect.anything(),
+ { page: page + 1 },
+ expect.anything(),
+ expect.anything(),
+ );
});
- it('calls disableKey when removing a key', async () => {
- await mountComponent();
+ it('moves to specified page', async () => {
+ await glPagination.vm.$emit('input', 5);
+
+ expect(pageMutationMock).toHaveBeenCalledWith(
+ expect.anything(),
+ { page: 5 },
+ expect.anything(),
+ expect.anything(),
+ );
+ });
- await removeKey('remove.key');
+ it('moves a page back if there are no more keys on this page', async () => {
+ await findModal().vm.$emit('remove');
+ await waitForPromises();
- expect(putMethodMock).toHaveBeenCalledWith(`${TEST_ENDPOINT}/${key.id}/disable`);
- expect(getMethodMock).toHaveBeenCalled();
+ expect(pageMutationMock).toHaveBeenCalledWith(
+ expect.anything(),
+ { page: page - 1 },
+ expect.anything(),
+ expect.anything(),
+ );
});
});
});