Commit 1a4ceaaf authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '262850-delete-schedule-dor-backend' into 'master'

Allow schedule destroy

See merge request gitlab-org/gitlab!49235
parents 1243e528 660d631d
...@@ -47,14 +47,17 @@ export default { ...@@ -47,14 +47,17 @@ export default {
}, },
methods: { methods: {
deleteSchedule() { deleteSchedule() {
const { projectPath } = this; const {
projectPath,
schedule: { iid },
} = this;
this.loading = true; this.loading = true;
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: destroyOncallScheduleMutation, mutation: destroyOncallScheduleMutation,
variables: { variables: {
id: this.schedule.id, iid,
projectPath, projectPath,
}, },
update(store, { data }) { update(store, { data }) {
...@@ -87,6 +90,7 @@ export default { ...@@ -87,6 +90,7 @@ export default {
ref="deleteScheduleModal" ref="deleteScheduleModal"
modal-id="deleteScheduleModal" modal-id="deleteScheduleModal"
size="sm" size="sm"
:data-testid="`delete-schedule-modal-${schedule.iid}`"
:title="$options.i18n.deleteSchedule" :title="$options.i18n.deleteSchedule"
:action-primary="primaryProps" :action-primary="primaryProps"
:action-cancel="cancelProps" :action-cancel="cancelProps"
......
mutation oncallScheduleDestroy($oncallScheduleDestroyInput: OncallScheduleDestroyInput!) { mutation oncallScheduleDestroy($iid: String!, $projectPath: ID!) {
oncallScheduleDestroy(input: $oncallScheduleDestroyInput) { oncallScheduleDestroy(input: { iid: $iid, projectPath: $projectPath }) {
errors errors
oncallSchedule { oncallSchedule {
iid iid
......
...@@ -4,6 +4,7 @@ exports[`DeleteScheduleModal renders delete schedule modal layout 1`] = ` ...@@ -4,6 +4,7 @@ exports[`DeleteScheduleModal renders delete schedule modal layout 1`] = `
<gl-modal-stub <gl-modal-stub
actioncancel="[object Object]" actioncancel="[object Object]"
actionprimary="[object Object]" actionprimary="[object Object]"
data-testid="delete-schedule-modal-37"
modalclass="" modalclass=""
modalid="deleteScheduleModal" modalid="deleteScheduleModal"
size="sm" size="sm"
......
/* eslint-disable no-unused-vars */
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import createMockApollo from 'jest/helpers/mock_apollo_helper'; import createMockApollo from 'jest/helpers/mock_apollo_helper';
import { GlModal, GlAlert, GlSprintf } from '@gitlab/ui'; import { GlModal, GlAlert, GlSprintf } from '@gitlab/ui';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import getOncallSchedulesQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
import destroyOncallScheduleMutation from 'ee/oncall_schedules/graphql/mutations/destroy_oncall_schedule.mutation.graphql'; import destroyOncallScheduleMutation from 'ee/oncall_schedules/graphql/mutations/destroy_oncall_schedule.mutation.graphql';
import DeleteScheduleModal, { import DeleteScheduleModal, {
i18n, i18n,
} from 'ee/oncall_schedules/components/delete_schedule_modal.vue'; } from 'ee/oncall_schedules/components/delete_schedule_modal.vue';
import { getOncallSchedulesQueryResponse, destroyScheduleResponse } from './mocks/apollo_mock'; import {
getOncallSchedulesQueryResponse,
destroyScheduleResponse,
destroyScheduleResponseWithErrors,
} from './mocks/apollo_mock';
const localVue = createLocalVue(); const localVue = createLocalVue();
const projectPath = 'group/project'; const projectPath = 'group/project';
const mutate = jest.fn(); const mutate = jest.fn();
const mockHideModal = jest.fn(); const mockHideModal = jest.fn();
const schedule =
getOncallSchedulesQueryResponse.data.project.incidentManagementOncallSchedules.nodes[0];
localVue.use(VueApollo); localVue.use(VueApollo);
...@@ -29,14 +35,14 @@ describe('DeleteScheduleModal', () => { ...@@ -29,14 +35,14 @@ describe('DeleteScheduleModal', () => {
async function awaitApolloDomMock() { async function awaitApolloDomMock() {
await wrapper.vm.$nextTick(); // kick off the DOM update await wrapper.vm.$nextTick(); // kick off the DOM update
await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises) await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises)
await wrapper.vm.$nextTick(); // kick off the DOM update for flash await wrapper.vm.$nextTick(); // kick off the DOM update
} }
async function destroySchedule(localWrapper) { async function destroySchedule(localWrapper) {
await jest.runOnlyPendingTimers(); await jest.runOnlyPendingTimers();
await localWrapper.vm.$nextTick(); await localWrapper.vm.$nextTick();
localWrapper.vm.$emit('primary'); localWrapper.find(GlModal).vm.$emit('primary', { preventDefault: jest.fn() });
} }
const createComponent = ({ data = {}, props = {} } = {}) => { const createComponent = ({ data = {}, props = {} } = {}) => {
...@@ -47,8 +53,7 @@ describe('DeleteScheduleModal', () => { ...@@ -47,8 +53,7 @@ describe('DeleteScheduleModal', () => {
}; };
}, },
propsData: { propsData: {
schedule: schedule,
getOncallSchedulesQueryResponse.data.project.incidentManagementOncallSchedules.nodes[0],
...props, ...props,
}, },
provide: { provide: {
...@@ -70,13 +75,27 @@ describe('DeleteScheduleModal', () => { ...@@ -70,13 +75,27 @@ describe('DeleteScheduleModal', () => {
localVue.use(VueApollo); localVue.use(VueApollo);
destroyScheduleHandler = destroyHandler; destroyScheduleHandler = destroyHandler;
const requestHandlers = [[destroyOncallScheduleMutation, destroyScheduleHandler]]; const requestHandlers = [
[getOncallSchedulesQuery, jest.fn().mockResolvedValue(getOncallSchedulesQueryResponse)],
[destroyOncallScheduleMutation, destroyScheduleHandler],
];
fakeApollo = createMockApollo(requestHandlers); fakeApollo = createMockApollo(requestHandlers);
fakeApollo.clients.defaultClient.cache.writeQuery({
query: getOncallSchedulesQuery,
variables: {
projectPath: 'group/project',
},
data: getOncallSchedulesQueryResponse.data,
});
wrapper = shallowMount(DeleteScheduleModal, { wrapper = shallowMount(DeleteScheduleModal, {
localVue, localVue,
apolloProvider: fakeApollo, apolloProvider: fakeApollo,
propsData: {
schedule,
},
provide: { provide: {
projectPath, projectPath,
}, },
...@@ -109,8 +128,7 @@ describe('DeleteScheduleModal', () => { ...@@ -109,8 +128,7 @@ describe('DeleteScheduleModal', () => {
expect(mutate).toHaveBeenCalledWith({ expect(mutate).toHaveBeenCalledWith({
mutation: expect.any(Object), mutation: expect.any(Object),
update: expect.anything(), update: expect.anything(),
// TODO: Once the BE is complete for the mutation update this spec to use the correct params variables: { iid: '37', projectPath },
variables: expect.anything(),
}); });
}); });
...@@ -134,6 +152,34 @@ describe('DeleteScheduleModal', () => { ...@@ -134,6 +152,34 @@ describe('DeleteScheduleModal', () => {
}); });
describe('with mocked Apollo client', () => { describe('with mocked Apollo client', () => {
// TODO: Once the BE is complete for the mutation add specs here for that via a destroyHandler it('has the name of the schedule to delete based on getOncallSchedulesQuery', async () => {
createComponentWithApollo();
await jest.runOnlyPendingTimers();
await wrapper.vm.$nextTick();
expect(findModal().attributes('data-testid')).toBe(`delete-schedule-modal-${schedule.iid}`);
});
it('calls a mutation with correct parameters and destroys a schedule', async () => {
createComponentWithApollo();
await destroySchedule(wrapper);
expect(destroyScheduleHandler).toHaveBeenCalled();
});
it('displays alert if mutation had a recoverable error', async () => {
createComponentWithApollo({
destroyHandler: jest.fn().mockResolvedValue(destroyScheduleResponseWithErrors),
});
await destroySchedule(wrapper);
await awaitApolloDomMock();
const alert = findAlert();
expect(alert.exists()).toBe(true);
expect(alert.text()).toContain('Houston, we have a problem');
});
}); });
}); });
...@@ -22,6 +22,7 @@ export const getOncallSchedulesQueryResponse = { ...@@ -22,6 +22,7 @@ export const getOncallSchedulesQueryResponse = {
incidentManagementOncallSchedules: { incidentManagementOncallSchedules: {
nodes: [ nodes: [
{ {
__typename: 'IncidentManagementOncallSchedule',
iid: '37', iid: '37',
name: 'Test schedule', name: 'Test schedule',
description: 'Description 1 lives here', description: 'Description 1 lives here',
...@@ -35,18 +36,12 @@ export const getOncallSchedulesQueryResponse = { ...@@ -35,18 +36,12 @@ export const getOncallSchedulesQueryResponse = {
}, },
}; };
export const scheduleToDestroy = {
iid: '37',
name: 'Test schedule',
description: 'Description 1 lives here',
timezone: 'Pacific/Honolulu',
};
export const destroyScheduleResponse = { export const destroyScheduleResponse = {
data: { data: {
oncallScheduleDestroy: { oncallScheduleDestroy: {
errors: [], errors: [],
oncallSchedule: { oncallSchedule: {
__typename: 'IncidentManagementOncallSchedule',
iid: '37', iid: '37',
name: 'Test schedule', name: 'Test schedule',
description: 'Description 1 lives here', description: 'Description 1 lives here',
...@@ -61,6 +56,7 @@ export const destroyScheduleResponseWithErrors = { ...@@ -61,6 +56,7 @@ export const destroyScheduleResponseWithErrors = {
oncallScheduleDestroy: { oncallScheduleDestroy: {
errors: ['Houston, we have a problem'], errors: ['Houston, we have a problem'],
oncallSchedule: { oncallSchedule: {
__typename: 'IncidentManagementOncallSchedule',
iid: '37', iid: '37',
name: 'Test schedule', name: 'Test schedule',
description: 'Description 1 lives here', description: 'Description 1 lives here',
...@@ -75,6 +71,7 @@ export const updateScheduleResponse = { ...@@ -75,6 +71,7 @@ export const updateScheduleResponse = {
oncallScheduleDestroy: { oncallScheduleDestroy: {
errors: [], errors: [],
oncallSchedule: { oncallSchedule: {
__typename: 'IncidentManagementOncallSchedule',
iid: '37', iid: '37',
name: 'Test schedule 2', name: 'Test schedule 2',
description: 'Description 2 lives here', description: 'Description 2 lives here',
......
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