Commit 8d591588 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '326196-devops-adoption-refactor-jest-tests' into 'master'

DevOps Adoption - Refactor jest tests

See merge request gitlab-org/gitlab!65229
parents f30de9a7 8b1df1c6
...@@ -21,12 +21,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; ...@@ -21,12 +21,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import DevopsScore from '~/analytics/devops_report/components/devops_score.vue'; import DevopsScore from '~/analytics/devops_report/components/devops_score.vue';
import API from '~/api'; import API from '~/api';
import { import { groupNodes, devopsAdoptionNamespaceData } from '../mock_data';
groupNodes,
groupPageInfo,
devopsAdoptionNamespaceData,
devopsAdoptionNamespaceDataEmpty,
} from '../mock_data';
jest.mock('ee/analytics/devops_report/devops_adoption/utils/cache_updates', () => ({ jest.mock('ee/analytics/devops_report/devops_adoption/utils/cache_updates', () => ({
addSegmentsToCache: jest.fn(), addSegmentsToCache: jest.fn(),
...@@ -35,39 +30,70 @@ jest.mock('ee/analytics/devops_report/devops_adoption/utils/cache_updates', () = ...@@ -35,39 +30,70 @@ jest.mock('ee/analytics/devops_report/devops_adoption/utils/cache_updates', () =
const localVue = createLocalVue(); const localVue = createLocalVue();
Vue.use(VueApollo); Vue.use(VueApollo);
const initialResponse = { const NETWORK_ERROR = new Error('foo!');
__typename: 'Groups',
nodes: groupNodes, const RESOURCE_TYPE_GROUP = 'groups';
pageInfo: groupPageInfo, const RESOURCE_TYPE_ENABLED_NAMESPACE = 'devopsAdoptionEnabledNamespaces';
const RESOURCE_TYPE_BULK_ENABLE_NAMESPACES = 'bulkEnableDevopsAdoptionNamespaces';
const STATE_EMPTY = 'empty';
const STATE_WITH_DATA = 'withData';
const STATE_NETWORK_ERROR = 'networkError';
const dataFactory = (resource) => {
switch (resource) {
case RESOURCE_TYPE_GROUP:
return { nodes: groupNodes };
case RESOURCE_TYPE_ENABLED_NAMESPACE:
return devopsAdoptionNamespaceData;
case RESOURCE_TYPE_BULK_ENABLE_NAMESPACES:
return {
enabledNamespaces: [devopsAdoptionNamespaceData.nodes[0]],
errors: [],
};
default:
return jest.fn();
}
};
const promiseFactory = (state, resource) => {
switch (state) {
case STATE_EMPTY:
return jest.fn().mockResolvedValue({
data: { [resource]: { nodes: [] } },
});
case STATE_WITH_DATA:
return jest.fn().mockResolvedValue({
data: { [resource]: dataFactory(resource) },
});
case STATE_NETWORK_ERROR:
return jest.fn().mockRejectedValue(NETWORK_ERROR);
default:
return jest.fn();
}
}; };
describe('DevopsAdoptionApp', () => { describe('DevopsAdoptionApp', () => {
let wrapper; let wrapper;
const groupsEmpty = jest.fn().mockResolvedValue({ __typename: 'Groups', nodes: [] }); const groupsEmpty = promiseFactory(STATE_EMPTY, RESOURCE_TYPE_GROUP);
const segmentsEmpty = jest.fn().mockResolvedValue({ const enabledNamespacesEmpty = promiseFactory(STATE_EMPTY, RESOURCE_TYPE_ENABLED_NAMESPACE);
data: { devopsAdoptionEnabledNamespaces: devopsAdoptionNamespaceDataEmpty }, const enableNamespacesMutationSpy = promiseFactory(
}); STATE_WITH_DATA,
const addSegmentMutationSpy = jest.fn().mockResolvedValue({ RESOURCE_TYPE_BULK_ENABLE_NAMESPACES,
data: { );
bulkEnableDevopsAdoptionNamespaces: {
enabledNamespaces: [devopsAdoptionNamespaceData.nodes[0]],
errors: [],
},
},
});
function createMockApolloProvider(options = {}) { function createMockApolloProvider(options = {}) {
const { const {
groupsSpy = groupsEmpty, groupsSpy = groupsEmpty,
segmentsSpy = segmentsEmpty, enabledNamespacesSpy = enabledNamespacesEmpty,
addSegmentsSpy = addSegmentMutationSpy, enableNamespacesMutation = enableNamespacesMutationSpy,
} = options; } = options;
const mockApollo = createMockApollo( const mockApollo = createMockApollo(
[ [
[bulkEnableDevopsAdoptionNamespacesMutation, addSegmentsSpy], [bulkEnableDevopsAdoptionNamespacesMutation, enableNamespacesMutation],
[devopsAdoptionEnabledNamespaces, segmentsSpy], [devopsAdoptionEnabledNamespaces, enabledNamespacesSpy],
], ],
{ {
Query: { Query: {
...@@ -117,7 +143,7 @@ describe('DevopsAdoptionApp', () => { ...@@ -117,7 +143,7 @@ describe('DevopsAdoptionApp', () => {
describe('when group data is present', () => { describe('when group data is present', () => {
beforeEach(async () => { beforeEach(async () => {
groupsSpy = jest.fn().mockResolvedValueOnce({ ...initialResponse, pageInfo: null }); groupsSpy = promiseFactory(STATE_WITH_DATA, RESOURCE_TYPE_GROUP);
const mockApollo = createMockApolloProvider({ groupsSpy }); const mockApollo = createMockApolloProvider({ groupsSpy });
wrapper = createComponent({ mockApollo }); wrapper = createComponent({ mockApollo });
await waitForPromises(); await waitForPromises();
...@@ -129,11 +155,9 @@ describe('DevopsAdoptionApp', () => { ...@@ -129,11 +155,9 @@ describe('DevopsAdoptionApp', () => {
}); });
describe('when error is thrown fetching group data', () => { describe('when error is thrown fetching group data', () => {
const error = new Error('foo!');
beforeEach(async () => { beforeEach(async () => {
jest.spyOn(Sentry, 'captureException'); jest.spyOn(Sentry, 'captureException');
groupsSpy = jest.fn().mockRejectedValueOnce(error); groupsSpy = promiseFactory(STATE_NETWORK_ERROR, RESOURCE_TYPE_GROUP);
const mockApollo = createMockApolloProvider({ groupsSpy }); const mockApollo = createMockApolloProvider({ groupsSpy });
wrapper = createComponent({ mockApollo }); wrapper = createComponent({ mockApollo });
await waitForPromises(); await waitForPromises();
...@@ -147,12 +171,12 @@ describe('DevopsAdoptionApp', () => { ...@@ -147,12 +171,12 @@ describe('DevopsAdoptionApp', () => {
const alert = wrapper.findComponent(GlAlert); const alert = wrapper.findComponent(GlAlert);
expect(alert.exists()).toBe(true); expect(alert.exists()).toBe(true);
expect(alert.text()).toBe(DEVOPS_ADOPTION_STRINGS.app.groupsError); expect(alert.text()).toBe(DEVOPS_ADOPTION_STRINGS.app.groupsError);
expect(Sentry.captureException.mock.calls[0][0].networkError).toBe(error); expect(Sentry.captureException.mock.calls[0][0].networkError).toBe(NETWORK_ERROR);
}); });
}); });
}); });
describe('segments data', () => { describe('enabled namespaces data', () => {
describe('when there is no active group', () => { describe('when there is no active group', () => {
beforeEach(async () => { beforeEach(async () => {
const mockApollo = createMockApolloProvider(); const mockApollo = createMockApolloProvider();
...@@ -161,7 +185,7 @@ describe('DevopsAdoptionApp', () => { ...@@ -161,7 +185,7 @@ describe('DevopsAdoptionApp', () => {
}); });
it('does not attempt to enable a group', () => { it('does not attempt to enable a group', () => {
expect(addSegmentMutationSpy).toHaveBeenCalledTimes(0); expect(enableNamespacesMutationSpy).toHaveBeenCalledTimes(0);
}); });
}); });
...@@ -170,11 +194,8 @@ describe('DevopsAdoptionApp', () => { ...@@ -170,11 +194,8 @@ describe('DevopsAdoptionApp', () => {
describe('which is enabled', () => { describe('which is enabled', () => {
beforeEach(async () => { beforeEach(async () => {
const segmentsWithData = jest.fn().mockResolvedValue({
data: { devopsAdoptionEnabledNamespaces: devopsAdoptionNamespaceData },
});
const mockApollo = createMockApolloProvider({ const mockApollo = createMockApolloProvider({
segmentsSpy: segmentsWithData, enabledNamespacesSpy: promiseFactory(STATE_WITH_DATA, RESOURCE_TYPE_ENABLED_NAMESPACE),
}); });
const provide = { const provide = {
isGroup: true, isGroup: true,
...@@ -186,7 +207,7 @@ describe('DevopsAdoptionApp', () => { ...@@ -186,7 +207,7 @@ describe('DevopsAdoptionApp', () => {
}); });
it('does not attempt to enable a group', () => { it('does not attempt to enable a group', () => {
expect(addSegmentMutationSpy).toHaveBeenCalledTimes(0); expect(enableNamespacesMutationSpy).toHaveBeenCalledTimes(0);
}); });
}); });
...@@ -204,8 +225,8 @@ describe('DevopsAdoptionApp', () => { ...@@ -204,8 +225,8 @@ describe('DevopsAdoptionApp', () => {
describe('enables the group', () => { describe('enables the group', () => {
it('makes a request with the correct variables', () => { it('makes a request with the correct variables', () => {
expect(addSegmentMutationSpy).toHaveBeenCalledTimes(1); expect(enableNamespacesMutationSpy).toHaveBeenCalledTimes(1);
expect(addSegmentMutationSpy).toHaveBeenCalledWith( expect(enableNamespacesMutationSpy).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
namespaceIds: [groupGid], namespaceIds: [groupGid],
displayNamespaceId: groupGid, displayNamespaceId: groupGid,
...@@ -225,16 +246,18 @@ describe('DevopsAdoptionApp', () => { ...@@ -225,16 +246,18 @@ describe('DevopsAdoptionApp', () => {
}); });
describe('error handling', () => { describe('error handling', () => {
const addSegmentsSpyErrorMessage = 'Error: bar!';
beforeEach(async () => { beforeEach(async () => {
jest.spyOn(Sentry, 'captureException'); jest.spyOn(Sentry, 'captureException');
const addSegmentsSpyError = jest.fn().mockRejectedValue(addSegmentsSpyErrorMessage);
const provide = { const provide = {
isGroup: true, isGroup: true,
groupGid, groupGid,
}; };
const mockApollo = createMockApolloProvider({ addSegmentsSpy: addSegmentsSpyError }); const mockApollo = createMockApolloProvider({
enableNamespacesMutation: promiseFactory(
STATE_NETWORK_ERROR,
RESOURCE_TYPE_BULK_ENABLE_NAMESPACES,
),
});
wrapper = createComponent({ mockApollo, provide }); wrapper = createComponent({ mockApollo, provide });
await waitForPromises(); await waitForPromises();
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
...@@ -251,9 +274,7 @@ describe('DevopsAdoptionApp', () => { ...@@ -251,9 +274,7 @@ describe('DevopsAdoptionApp', () => {
}); });
it('calls Sentry', () => { it('calls Sentry', () => {
expect(Sentry.captureException.mock.calls[0][0].networkError).toBe( expect(Sentry.captureException.mock.calls[0][0].networkError).toBe(NETWORK_ERROR);
addSegmentsSpyErrorMessage,
);
}); });
}); });
}); });
...@@ -261,12 +282,14 @@ describe('DevopsAdoptionApp', () => { ...@@ -261,12 +282,14 @@ describe('DevopsAdoptionApp', () => {
}); });
describe('when there is an error', () => { describe('when there is an error', () => {
const segmentsErrorMessage = 'Error: bar!';
beforeEach(async () => { beforeEach(async () => {
jest.spyOn(Sentry, 'captureException'); jest.spyOn(Sentry, 'captureException');
const segmentsError = jest.fn().mockRejectedValue(segmentsErrorMessage); const mockApollo = createMockApolloProvider({
const mockApollo = createMockApolloProvider({ segmentsSpy: segmentsError }); enabledNamespacesSpy: promiseFactory(
STATE_NETWORK_ERROR,
RESOURCE_TYPE_ENABLED_NAMESPACE,
),
});
wrapper = createComponent({ mockApollo }); wrapper = createComponent({ mockApollo });
await waitForPromises(); await waitForPromises();
}); });
...@@ -282,7 +305,7 @@ describe('DevopsAdoptionApp', () => { ...@@ -282,7 +305,7 @@ describe('DevopsAdoptionApp', () => {
}); });
it('calls Sentry', () => { it('calls Sentry', () => {
expect(Sentry.captureException.mock.calls[0][0].networkError).toBe(segmentsErrorMessage); expect(Sentry.captureException.mock.calls[0][0].networkError).toBe(NETWORK_ERROR);
}); });
}); });
...@@ -295,7 +318,7 @@ describe('DevopsAdoptionApp', () => { ...@@ -295,7 +318,7 @@ describe('DevopsAdoptionApp', () => {
wrapper = createComponent({ wrapper = createComponent({
mockApollo: createMockApolloProvider({ mockApollo: createMockApolloProvider({
groupsSpy: jest.fn().mockResolvedValueOnce({ ...initialResponse, pageInfo: null }), groupsSpy: promiseFactory(STATE_WITH_DATA, RESOURCE_TYPE_ENABLED_NAMESPACE),
}), }),
}); });
......
...@@ -25,10 +25,6 @@ export const groupIds = [1, 2]; ...@@ -25,10 +25,6 @@ export const groupIds = [1, 2];
export const groupGids = ['gid://gitlab/Group/1', 'gid://gitlab/Group/2']; export const groupGids = ['gid://gitlab/Group/1', 'gid://gitlab/Group/2'];
export const groupPageInfo = {
nextPage: 2,
};
export const devopsAdoptionNamespaceData = { export const devopsAdoptionNamespaceData = {
nodes: [ nodes: [
{ {
...@@ -66,11 +62,6 @@ export const devopsAdoptionNamespaceData = { ...@@ -66,11 +62,6 @@ export const devopsAdoptionNamespaceData = {
__typename: 'devopsAdoptionEnabledNamespaces', __typename: 'devopsAdoptionEnabledNamespaces',
}; };
export const devopsAdoptionNamespaceDataEmpty = {
nodes: [],
__typename: 'devopsAdoptionSegments',
};
export const devopsAdoptionTableHeaders = [ export const devopsAdoptionTableHeaders = [
{ {
index: 0, index: 0,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment