Commit 836963e4 authored by Miguel Rincon's avatar Miguel Rincon

Merge branch '321083-fe-group-level-devops-adoption-show-data-table-for-group' into 'master'

Group-level "DevOps Adoption" - Sync graphql variables

See merge request gitlab-org/gitlab!58744
parents 3f139e5d f75fa8a4
...@@ -22,7 +22,7 @@ import { ...@@ -22,7 +22,7 @@ import {
import bulkFindOrCreateDevopsAdoptionSegmentsMutation from '../graphql/mutations/bulk_find_or_create_devops_adoption_segments.mutation.graphql'; import bulkFindOrCreateDevopsAdoptionSegmentsMutation from '../graphql/mutations/bulk_find_or_create_devops_adoption_segments.mutation.graphql';
import devopsAdoptionSegmentsQuery from '../graphql/queries/devops_adoption_segments.query.graphql'; import devopsAdoptionSegmentsQuery from '../graphql/queries/devops_adoption_segments.query.graphql';
import getGroupsQuery from '../graphql/queries/get_groups.query.graphql'; import getGroupsQuery from '../graphql/queries/get_groups.query.graphql';
import { addSegmentsToCache } from '../utils/cache_updates'; import { addSegmentsToCache, deleteSegmentsFromCache } from '../utils/cache_updates';
import { shouldPollTableData } from '../utils/helpers'; import { shouldPollTableData } from '../utils/helpers';
import DevopsAdoptionEmptyState from './devops_adoption_empty_state.vue'; import DevopsAdoptionEmptyState from './devops_adoption_empty_state.vue';
import DevopsAdoptionSegmentModal from './devops_adoption_segment_modal.vue'; import DevopsAdoptionSegmentModal from './devops_adoption_segment_modal.vue';
...@@ -74,7 +74,7 @@ export default { ...@@ -74,7 +74,7 @@ export default {
pageInfo: null, pageInfo: null,
}, },
pollingTableData: null, pollingTableData: null,
variables: this.isGroup segmentsQueryVariables: this.isGroup
? { ? {
parentNamespaceId: this.groupGid, parentNamespaceId: this.groupGid,
directDescendantsOnly: false, directDescendantsOnly: false,
...@@ -86,7 +86,7 @@ export default { ...@@ -86,7 +86,7 @@ export default {
devopsAdoptionSegments: { devopsAdoptionSegments: {
query: devopsAdoptionSegmentsQuery, query: devopsAdoptionSegmentsQuery,
variables() { variables() {
return this.variables; return this.segmentsQueryVariables;
}, },
result({ data }) { result({ data }) {
if (this.isGroup) { if (this.isGroup) {
...@@ -166,7 +166,7 @@ export default { ...@@ -166,7 +166,7 @@ export default {
if (errors.length) { if (errors.length) {
this.handleError(DEVOPS_ADOPTION_ERROR_KEYS.addSegment, errors); this.handleError(DEVOPS_ADOPTION_ERROR_KEYS.addSegment, errors);
} else { } else {
addSegmentsToCache(store, segments, this.variables); this.addSegmentsToCache(segments);
} }
}, },
}) })
...@@ -232,6 +232,16 @@ export default { ...@@ -232,6 +232,16 @@ export default {
clearSelectedSegment() { clearSelectedSegment() {
this.selectedSegment = null; this.selectedSegment = null;
}, },
addSegmentsToCache(segments) {
const { cache } = this.$apollo.getClient();
addSegmentsToCache(cache, segments, this.segmentsQueryVariables);
},
deleteSegmentsFromCache(ids) {
const { cache } = this.$apollo.getClient();
deleteSegmentsFromCache(cache, ids, this.segmentsQueryVariables);
},
}, },
}; };
</script> </script>
...@@ -250,6 +260,8 @@ export default { ...@@ -250,6 +260,8 @@ export default {
:key="modalKey" :key="modalKey"
:groups="groups.nodes" :groups="groups.nodes"
:enabled-groups="devopsAdoptionSegments.nodes" :enabled-groups="devopsAdoptionSegments.nodes"
@segmentsAdded="addSegmentsToCache"
@segmentsRemoved="deleteSegmentsFromCache"
@trackModalOpenState="trackModalOpenState" @trackModalOpenState="trackModalOpenState"
/> />
<div v-if="hasSegmentsData" class="gl-mt-3"> <div v-if="hasSegmentsData" class="gl-mt-3">
...@@ -279,6 +291,7 @@ export default { ...@@ -279,6 +291,7 @@ export default {
:segments="devopsAdoptionSegments.nodes" :segments="devopsAdoptionSegments.nodes"
:selected-segment="selectedSegment" :selected-segment="selectedSegment"
@set-selected-segment="setSelectedSegment" @set-selected-segment="setSelectedSegment"
@segmentsRemoved="deleteSegmentsFromCache"
@trackModalOpenState="trackModalOpenState" @trackModalOpenState="trackModalOpenState"
/> />
</div> </div>
......
...@@ -3,7 +3,6 @@ import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui'; ...@@ -3,7 +3,6 @@ import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { DEVOPS_ADOPTION_STRINGS, DEVOPS_ADOPTION_SEGMENT_DELETE_MODAL_ID } from '../constants'; import { DEVOPS_ADOPTION_STRINGS, DEVOPS_ADOPTION_SEGMENT_DELETE_MODAL_ID } from '../constants';
import deleteDevopsAdoptionSegmentMutation from '../graphql/mutations/delete_devops_adoption_segment.mutation.graphql'; import deleteDevopsAdoptionSegmentMutation from '../graphql/mutations/delete_devops_adoption_segment.mutation.graphql';
import { deleteSegmentsFromCache } from '../utils/cache_updates';
export default { export default {
name: 'DevopsAdoptionDeleteModal', name: 'DevopsAdoptionDeleteModal',
...@@ -65,8 +64,8 @@ export default { ...@@ -65,8 +64,8 @@ export default {
variables: { variables: {
id: [id], id: [id],
}, },
update(store) { update: () => {
deleteSegmentsFromCache(store, [id]); this.$emit('segmentsRemoved', [id]);
}, },
}); });
......
...@@ -10,7 +10,6 @@ import { ...@@ -10,7 +10,6 @@ import {
} from '../constants'; } from '../constants';
import bulkFindOrCreateDevopsAdoptionSegmentsMutation from '../graphql/mutations/bulk_find_or_create_devops_adoption_segments.mutation.graphql'; import bulkFindOrCreateDevopsAdoptionSegmentsMutation from '../graphql/mutations/bulk_find_or_create_devops_adoption_segments.mutation.graphql';
import deleteDevopsAdoptionSegmentMutation from '../graphql/mutations/delete_devops_adoption_segment.mutation.graphql'; import deleteDevopsAdoptionSegmentMutation from '../graphql/mutations/delete_devops_adoption_segment.mutation.graphql';
import { addSegmentsToCache, deleteSegmentsFromCache } from '../utils/cache_updates';
export default { export default {
name: 'DevopsAdoptionSegmentModal', name: 'DevopsAdoptionSegmentModal',
...@@ -26,6 +25,9 @@ export default { ...@@ -26,6 +25,9 @@ export default {
isGroup: { isGroup: {
default: false, default: false,
}, },
groupGid: {
default: null,
},
}, },
props: { props: {
groups: { groups: {
...@@ -139,7 +141,7 @@ export default { ...@@ -139,7 +141,7 @@ export default {
bulkFindOrCreateDevopsAdoptionSegments: { segments, errors: requestErrors }, bulkFindOrCreateDevopsAdoptionSegments: { segments, errors: requestErrors },
} = data; } = data;
if (!requestErrors.length) addSegmentsToCache(store, segments); if (!requestErrors.length) this.$emit('segmentsAdded', segments);
}, },
}); });
...@@ -157,7 +159,11 @@ export default { ...@@ -157,7 +159,11 @@ export default {
async deleteMissingGroups() { async deleteMissingGroups() {
try { try {
const removedGroupGids = this.enabledGroups const removedGroupGids = this.enabledGroups
.filter((group) => !this.checkboxValues.includes(getIdFromGraphQLId(group.namespace.id))) .filter(
(group) =>
!this.checkboxValues.includes(getIdFromGraphQLId(group.namespace.id)) &&
group.namespace.id !== this.groupGid,
)
.map((group) => group.id); .map((group) => group.id);
if (removedGroupGids.length) { if (removedGroupGids.length) {
...@@ -177,7 +183,7 @@ export default { ...@@ -177,7 +183,7 @@ export default {
deleteDevopsAdoptionSegment: { errors: requestErrors }, deleteDevopsAdoptionSegment: { errors: requestErrors },
} = data; } = data;
if (!requestErrors.length) deleteSegmentsFromCache(store, removedGroupGids); if (!requestErrors.length) this.$emit('segmentsRemoved', removedGroupGids);
}, },
}); });
...@@ -199,7 +205,6 @@ export default { ...@@ -199,7 +205,6 @@ export default {
this.$refs.modal.hide(); this.$refs.modal.hide();
}, },
resetForm() { resetForm() {
this.checkboxValues = [];
this.filter = ''; this.filter = '';
this.$emit('trackModalOpenState', false); this.$emit('trackModalOpenState', false);
}, },
......
...@@ -253,6 +253,7 @@ export default { ...@@ -253,6 +253,7 @@ export default {
<devops-adoption-delete-modal <devops-adoption-delete-modal
v-if="selectedSegment" v-if="selectedSegment"
:segment="selectedSegment" :segment="selectedSegment"
@segmentsRemoved="$emit('segmentsRemoved', $event)"
@trackModalOpenState="$emit('trackModalOpenState', $event)" @trackModalOpenState="$emit('trackModalOpenState', $event)"
/> />
</div> </div>
......
query($parentNamespaceId: NamespaceID, $directDescendantsOnly: Boolean) { query devopsAdoptionSegments($parentNamespaceId: NamespaceID, $directDescendantsOnly: Boolean) {
devopsAdoptionSegments( devopsAdoptionSegments(
parentNamespaceId: $parentNamespaceId parentNamespaceId: $parentNamespaceId
directDescendantsOnly: $directDescendantsOnly directDescendantsOnly: $directDescendantsOnly
......
...@@ -21,9 +21,10 @@ export const addSegmentsToCache = (store, segments, variables) => { ...@@ -21,9 +21,10 @@ export const addSegmentsToCache = (store, segments, variables) => {
}); });
}; };
export const deleteSegmentsFromCache = (store, segmentIds) => { export const deleteSegmentsFromCache = (store, segmentIds, variables) => {
const sourceData = store.readQuery({ const sourceData = store.readQuery({
query: devopsAdoptionSegmentsQuery, query: devopsAdoptionSegmentsQuery,
variables,
}); });
const updatedData = produce(sourceData, (draftData) => { const updatedData = produce(sourceData, (draftData) => {
...@@ -34,6 +35,7 @@ export const deleteSegmentsFromCache = (store, segmentIds) => { ...@@ -34,6 +35,7 @@ export const deleteSegmentsFromCache = (store, segmentIds) => {
store.writeQuery({ store.writeQuery({
query: devopsAdoptionSegmentsQuery, query: devopsAdoptionSegmentsQuery,
variables,
data: updatedData, data: updatedData,
}); });
}; };
...@@ -515,7 +515,18 @@ describe('DevopsAdoptionApp', () => { ...@@ -515,7 +515,18 @@ describe('DevopsAdoptionApp', () => {
namespaceIds: [groupGid], namespaceIds: [groupGid],
}), }),
); );
});
it('calls addSegmentsToCache with the correct variables', () => {
expect(addSegmentsToCache).toHaveBeenCalledTimes(1); expect(addSegmentsToCache).toHaveBeenCalledTimes(1);
expect(addSegmentsToCache).toHaveBeenCalledWith(
expect.anything(),
[devopsAdoptionSegmentsData.nodes[0]],
{
parentNamespaceId: groupGid,
directDescendantsOnly: false,
},
);
}); });
describe('error handling', () => { describe('error handling', () => {
......
import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui'; import { GlModal, GlSprintf, GlAlert } from '@gitlab/ui';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import { ApolloMutation } from 'vue-apollo'; import Vue from 'vue';
import VueApollo from 'vue-apollo';
import DevopsAdoptionDeleteModal from 'ee/analytics/devops_report/devops_adoption/components/devops_adoption_delete_modal.vue'; import DevopsAdoptionDeleteModal from 'ee/analytics/devops_report/devops_adoption/components/devops_adoption_delete_modal.vue';
import { DEVOPS_ADOPTION_SEGMENT_DELETE_MODAL_ID } from 'ee/analytics/devops_report/devops_adoption/constants'; import { DEVOPS_ADOPTION_SEGMENT_DELETE_MODAL_ID } from 'ee/analytics/devops_report/devops_adoption/constants';
import deleteDevopsAdoptionSegmentMutation from 'ee/analytics/devops_report/devops_adoption/graphql/mutations/delete_devops_adoption_segment.mutation.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { import {
genericDeleteErrorMessage, genericDeleteErrorMessage,
...@@ -11,6 +14,9 @@ import { ...@@ -11,6 +14,9 @@ import {
devopsAdoptionSegmentsData, devopsAdoptionSegmentsData,
} from '../mock_data'; } from '../mock_data';
const localVue = createLocalVue();
Vue.use(VueApollo);
const mockEvent = { preventDefault: jest.fn() }; const mockEvent = { preventDefault: jest.fn() };
const mutate = jest.fn().mockResolvedValue({ const mutate = jest.fn().mockResolvedValue({
data: { data: {
...@@ -32,21 +38,18 @@ const mutateWithErrors = jest.fn().mockRejectedValue(genericDeleteErrorMessage); ...@@ -32,21 +38,18 @@ const mutateWithErrors = jest.fn().mockRejectedValue(genericDeleteErrorMessage);
describe('DevopsAdoptionDeleteModal', () => { describe('DevopsAdoptionDeleteModal', () => {
let wrapper; let wrapper;
const createComponent = ({ mutationMock = mutate } = {}) => { const createComponent = ({ deleteSegmentsSpy = mutate, props = {} } = {}) => {
const $apollo = { const mockApollo = createMockApollo([[deleteDevopsAdoptionSegmentMutation, deleteSegmentsSpy]]);
mutate: mutationMock,
};
wrapper = shallowMount(DevopsAdoptionDeleteModal, { wrapper = shallowMount(DevopsAdoptionDeleteModal, {
localVue,
apolloProvider: mockApollo,
propsData: { propsData: {
segment: devopsAdoptionSegmentsData.nodes[0], segment: devopsAdoptionSegmentsData.nodes[0],
...props,
}, },
stubs: { stubs: {
GlSprintf, GlSprintf,
ApolloMutation,
},
mocks: {
$apollo,
}, },
}); });
}; };
...@@ -99,7 +102,7 @@ describe('DevopsAdoptionDeleteModal', () => { ...@@ -99,7 +102,7 @@ describe('DevopsAdoptionDeleteModal', () => {
describe('submitting the form', () => { describe('submitting the form', () => {
describe('while waiting for the mutation', () => { describe('while waiting for the mutation', () => {
beforeEach(() => createComponent({ mutationMock: mutateLoading })); beforeEach(() => createComponent({ deleteSegmentsSpy: mutateLoading }));
it('disables the cancel button', async () => { it('disables the cancel button', async () => {
expect(cancelButtonDisabledState()).toBe(false); expect(cancelButtonDisabledState()).toBe(false);
...@@ -132,13 +135,15 @@ describe('DevopsAdoptionDeleteModal', () => { ...@@ -132,13 +135,15 @@ describe('DevopsAdoptionDeleteModal', () => {
}); });
it('submits the correct request variables', () => { it('submits the correct request variables', () => {
expect(mutate).toHaveBeenCalledWith( expect(mutate).toHaveBeenCalledWith({
expect.objectContaining({ id: [devopsAdoptionSegmentsData.nodes[0].id],
variables: { });
id: [devopsAdoptionSegmentsData.nodes[0].id], });
},
}), it('emits segmentsRemoved with the correct variables', () => {
); const [params] = wrapper.emitted().segmentsRemoved[0];
expect(params).toStrictEqual([devopsAdoptionSegmentsData.nodes[0].id]);
}); });
it('closes the modal after a successful mutation', () => { it('closes the modal after a successful mutation', () => {
...@@ -154,7 +159,7 @@ describe('DevopsAdoptionDeleteModal', () => { ...@@ -154,7 +159,7 @@ describe('DevopsAdoptionDeleteModal', () => {
`( `(
'displays a $errorType error if the mutation has a $errorLocation error', 'displays a $errorType error if the mutation has a $errorLocation error',
async ({ mutationSpy, message }) => { async ({ mutationSpy, message }) => {
createComponent({ mutationMock: mutationSpy }); createComponent({ deleteSegmentsSpy: mutationSpy });
findModal().vm.$emit('primary', mockEvent); findModal().vm.$emit('primary', mockEvent);
...@@ -171,13 +176,15 @@ describe('DevopsAdoptionDeleteModal', () => { ...@@ -171,13 +176,15 @@ describe('DevopsAdoptionDeleteModal', () => {
it('calls sentry on top level error', async () => { it('calls sentry on top level error', async () => {
jest.spyOn(Sentry, 'captureException'); jest.spyOn(Sentry, 'captureException');
createComponent({ mutationMock: mutateWithErrors }); createComponent({ deleteSegmentsSpy: mutateWithErrors });
findModal().vm.$emit('primary', mockEvent); findModal().vm.$emit('primary', mockEvent);
await waitForPromises(); await waitForPromises();
expect(Sentry.captureException.mock.calls[0][0]).toBe(genericDeleteErrorMessage); expect(Sentry.captureException.mock.calls[0][0].networkError).toBe(
genericDeleteErrorMessage,
);
}); });
}); });
}); });
......
import { GlModal, GlFormInput, GlSprintf, GlAlert, GlIcon } from '@gitlab/ui'; import { GlModal, GlFormInput, GlSprintf, GlAlert, GlIcon } from '@gitlab/ui';
import * as Sentry from '@sentry/browser'; import * as Sentry from '@sentry/browser';
import { shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue'; import Vue, { nextTick } from 'vue';
import { ApolloMutation } from 'vue-apollo'; import VueApollo from 'vue-apollo';
import DevopsAdoptionSegmentModal from 'ee/analytics/devops_report/devops_adoption/components/devops_adoption_segment_modal.vue'; import DevopsAdoptionSegmentModal from 'ee/analytics/devops_report/devops_adoption/components/devops_adoption_segment_modal.vue';
import { DEVOPS_ADOPTION_SEGMENT_MODAL_ID } from 'ee/analytics/devops_report/devops_adoption/constants'; import { DEVOPS_ADOPTION_SEGMENT_MODAL_ID } from 'ee/analytics/devops_report/devops_adoption/constants';
import bulkFindOrCreateDevopsAdoptionSegmentsMutation from 'ee/analytics/devops_report/devops_adoption/graphql/mutations/bulk_find_or_create_devops_adoption_segments.mutation.graphql';
import deleteDevopsAdoptionSegmentMutation from 'ee/analytics/devops_report/devops_adoption/graphql/mutations/delete_devops_adoption_segment.mutation.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { import {
groupNodes, groupNodes,
...@@ -16,13 +19,18 @@ import { ...@@ -16,13 +19,18 @@ import {
devopsAdoptionSegmentsData, devopsAdoptionSegmentsData,
} from '../mock_data'; } from '../mock_data';
const localVue = createLocalVue();
Vue.use(VueApollo);
const mockEvent = { preventDefault: jest.fn() }; const mockEvent = { preventDefault: jest.fn() };
const mutate = jest.fn().mockResolvedValue({ const mutate = jest.fn().mockResolvedValue({
data: { data: {
bulkFindOrCreateDevopsAdoptionSegments: { bulkFindOrCreateDevopsAdoptionSegments: {
segments: [devopsAdoptionSegmentsData.nodes[0]],
errors: [], errors: [],
}, },
deleteDevopsAdoptionSegment: { deleteDevopsAdoptionSegment: {
segments: [devopsAdoptionSegmentsData.nodes[0]],
errors: [], errors: [],
}, },
}, },
...@@ -31,9 +39,11 @@ const mutateWithDataErrors = jest.fn().mockResolvedValue({ ...@@ -31,9 +39,11 @@ const mutateWithDataErrors = jest.fn().mockResolvedValue({
data: { data: {
bulkFindOrCreateDevopsAdoptionSegments: { bulkFindOrCreateDevopsAdoptionSegments: {
errors: [dataErrorMessage], errors: [dataErrorMessage],
segments: [],
}, },
deleteDevopsAdoptionSegment: { deleteDevopsAdoptionSegment: {
errors: [], errors: [dataErrorMessage],
segments: [],
}, },
}, },
}); });
...@@ -43,12 +53,20 @@ const mutateWithErrors = jest.fn().mockRejectedValue(genericErrorMessage); ...@@ -43,12 +53,20 @@ const mutateWithErrors = jest.fn().mockRejectedValue(genericErrorMessage);
describe('DevopsAdoptionSegmentModal', () => { describe('DevopsAdoptionSegmentModal', () => {
let wrapper; let wrapper;
const createComponent = ({ mutationMock = mutate, props = {}, provide = {} } = {}) => { const createComponent = ({
const $apollo = { deleteSegmentsSpy = mutate,
mutate: mutationMock, addSegmentsSpy = mutate,
}; props = {},
provide = {},
} = {}) => {
const mockApollo = createMockApollo([
[deleteDevopsAdoptionSegmentMutation, deleteSegmentsSpy],
[bulkFindOrCreateDevopsAdoptionSegmentsMutation, addSegmentsSpy],
]);
wrapper = shallowMount(DevopsAdoptionSegmentModal, { wrapper = shallowMount(DevopsAdoptionSegmentModal, {
localVue,
apolloProvider: mockApollo,
propsData: { propsData: {
groups: groupNodes, groups: groupNodes,
...props, ...props,
...@@ -56,12 +74,10 @@ describe('DevopsAdoptionSegmentModal', () => { ...@@ -56,12 +74,10 @@ describe('DevopsAdoptionSegmentModal', () => {
provide, provide,
stubs: { stubs: {
GlSprintf, GlSprintf,
ApolloMutation,
},
mocks: {
$apollo,
}, },
}); });
wrapper.vm.$refs.modal.hide = jest.fn();
}; };
const findModal = () => wrapper.find(GlModal); const findModal = () => wrapper.find(GlModal);
...@@ -274,49 +290,48 @@ describe('DevopsAdoptionSegmentModal', () => { ...@@ -274,49 +290,48 @@ describe('DevopsAdoptionSegmentModal', () => {
`( `(
'$action groups', '$action groups',
({ enabledGroups, newGroups, expectedAddGroupGids, expectedDeleteIds }) => { ({ enabledGroups, newGroups, expectedAddGroupGids, expectedDeleteIds }) => {
describe('successful submission', () => { beforeEach(async () => {
beforeEach(async () => { createComponent({ props: { enabledGroups } });
createComponent({ props: { enabledGroups } });
wrapper.setData(newGroups); wrapper.setData(newGroups);
wrapper.vm.$refs.modal.hide = jest.fn(); findModal().vm.$emit('primary', mockEvent);
findModal().vm.$emit('primary', mockEvent); await waitForPromises();
});
await waitForPromises(); if (expectedAddGroupGids.length) {
it('submits the correct add request variables', () => {
expect(mutate).toHaveBeenCalledWith({ namespaceIds: expectedAddGroupGids });
}); });
if (expectedAddGroupGids.length) { it('emits segmentsAdded with the correct variables', () => {
it('submits the correct add request variables', () => { const [params] = wrapper.emitted().segmentsAdded[0];
expect(mutate).toHaveBeenCalledWith(
expect.objectContaining({ expect(params).toStrictEqual([devopsAdoptionSegmentsData.nodes[0]]);
variables: { namespaceIds: expectedAddGroupGids }, });
}), }
);
}); if (expectedDeleteIds.length) {
} it('submits the correct delete request variables', () => {
expect(mutate).toHaveBeenCalledWith({ id: expectedDeleteIds });
if (expectedDeleteIds.length) {
it('submits the correct delete request variables', () => {
expect(mutate).toHaveBeenCalledWith(
expect.objectContaining({
variables: { id: expectedDeleteIds },
}),
);
});
}
it('closes the modal after a successful mutation', () => {
expect(wrapper.vm.$refs.modal.hide).toHaveBeenCalled();
}); });
it('resets the form fields', () => { it('emits segmentsRemoved with the correct variables', () => {
findModal().vm.$emit('hidden'); const [params] = wrapper.emitted().segmentsRemoved[0];
expect(wrapper.vm.checkboxValues).toEqual([]); expect(params).toStrictEqual(firstGroupId);
expect(wrapper.vm.filter).toBe('');
}); });
}
it('closes the modal after a successful mutation', () => {
expect(wrapper.vm.$refs.modal.hide).toHaveBeenCalled();
});
it('resets the filter', () => {
findModal().vm.$emit('hidden');
expect(wrapper.vm.filter).toBe('');
}); });
}, },
); );
...@@ -329,7 +344,7 @@ describe('DevopsAdoptionSegmentModal', () => { ...@@ -329,7 +344,7 @@ describe('DevopsAdoptionSegmentModal', () => {
`( `(
'displays a $errorType error if the mutation has a $errorLocation error', 'displays a $errorType error if the mutation has a $errorLocation error',
async ({ mutationSpy, message }) => { async ({ mutationSpy, message }) => {
createComponent({ mutationMock: mutationSpy }); createComponent({ addSegmentsSpy: mutationSpy, deleteSegmentsSpy: mutationSpy });
wrapper.setData(enableFirstGroup); wrapper.setData(enableFirstGroup);
...@@ -348,7 +363,10 @@ describe('DevopsAdoptionSegmentModal', () => { ...@@ -348,7 +363,10 @@ describe('DevopsAdoptionSegmentModal', () => {
it('calls sentry on top level error', async () => { it('calls sentry on top level error', async () => {
const captureException = jest.spyOn(Sentry, 'captureException'); const captureException = jest.spyOn(Sentry, 'captureException');
createComponent({ mutationMock: mutateWithErrors }); createComponent({
addSegmentsSpy: mutateWithErrors,
deleteSegmentsSpy: mutateWithErrors,
});
wrapper.setData(enableFirstGroup); wrapper.setData(enableFirstGroup);
...@@ -356,7 +374,7 @@ describe('DevopsAdoptionSegmentModal', () => { ...@@ -356,7 +374,7 @@ describe('DevopsAdoptionSegmentModal', () => {
await waitForPromises(); await waitForPromises();
expect(captureException).toHaveBeenCalledWith(genericErrorMessage); expect(captureException.mock.calls[0][0].networkError).toBe(genericErrorMessage);
}); });
}); });
}); });
......
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