Commit 17832886 authored by David O'Regan's avatar David O'Regan

Merge branch '262852-adjsut-schedule-timeframe-cache-updates' into 'master'

Fix(oncallschedule): update oncall schedule's apollo cache methods

See merge request gitlab-org/gitlab!52773
parents b7d21377 b3b25252
...@@ -4,7 +4,7 @@ import { isEmpty } from 'lodash'; ...@@ -4,7 +4,7 @@ import { isEmpty } from 'lodash';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
import createOncallScheduleMutation from '../graphql/mutations/create_oncall_schedule.mutation.graphql'; import createOncallScheduleMutation from '../graphql/mutations/create_oncall_schedule.mutation.graphql';
import updateOncallScheduleMutation from '../graphql/mutations/update_oncall_schedule.mutation.graphql'; import updateOncallScheduleMutation from '../graphql/mutations/update_oncall_schedule.mutation.graphql';
import getOncallSchedulesQuery from '../graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from '../graphql/queries/get_oncall_schedules.query.graphql';
import { updateStoreOnScheduleCreate, updateStoreAfterScheduleEdit } from '../utils/cache_updates'; import { updateStoreOnScheduleCreate, updateStoreAfterScheduleEdit } from '../utils/cache_updates';
import { isNameFieldValid } from '../utils/common_utils'; import { isNameFieldValid } from '../utils/common_utils';
import AddEditScheduleForm from './add_edit_schedule_form.vue'; import AddEditScheduleForm from './add_edit_schedule_form.vue';
...@@ -106,8 +106,8 @@ export default { ...@@ -106,8 +106,8 @@ export default {
timezone: this.form.timezone.identifier, timezone: this.form.timezone.identifier,
}, },
}, },
update(store, { data: { oncallScheduleCreate } }) { update(store, { data }) {
updateStoreOnScheduleCreate(store, getOncallSchedulesQuery, oncallScheduleCreate, { updateStoreOnScheduleCreate(store, getOncallSchedulesWithRotationsQuery, data, {
projectPath, projectPath,
}); });
}, },
...@@ -143,7 +143,9 @@ export default { ...@@ -143,7 +143,9 @@ export default {
mutation: updateOncallScheduleMutation, mutation: updateOncallScheduleMutation,
variables: this.editScheduleVariables, variables: this.editScheduleVariables,
update(store, { data }) { update(store, { data }) {
updateStoreAfterScheduleEdit(store, getOncallSchedulesQuery, data, { projectPath }); updateStoreAfterScheduleEdit(store, getOncallSchedulesWithRotationsQuery, data, {
projectPath,
});
}, },
}) })
.then( .then(
......
...@@ -4,8 +4,6 @@ import { ...@@ -4,8 +4,6 @@ import {
GlCard, GlCard,
GlButtonGroup, GlButtonGroup,
GlButton, GlButton,
GlDropdown,
GlDropdownItem,
GlModalDirective, GlModalDirective,
GlTooltipDirective, GlTooltipDirective,
} from '@gitlab/ui'; } from '@gitlab/ui';
...@@ -50,8 +48,6 @@ export default { ...@@ -50,8 +48,6 @@ export default {
GlButton, GlButton,
GlButtonGroup, GlButtonGroup,
GlCard, GlCard,
GlDropdown,
GlDropdownItem,
GlSprintf, GlSprintf,
AddEditRotationModal, AddEditRotationModal,
DeleteScheduleModal, DeleteScheduleModal,
...@@ -86,7 +82,7 @@ export default { ...@@ -86,7 +82,7 @@ export default {
}, },
update(data) { update(data) {
const nodes = data.project?.incidentManagementOncallSchedules?.nodes ?? []; const nodes = data.project?.incidentManagementOncallSchedules?.nodes ?? [];
const schedule = nodes.pop() || {}; const schedule = nodes.length ? nodes[nodes.length - 1] : null;
return schedule?.rotations.nodes ?? []; return schedule?.rotations.nodes ?? [];
}, },
error(error) { error(error) {
...@@ -202,16 +198,17 @@ export default { ...@@ -202,16 +198,17 @@ export default {
<template #timezone>{{ schedule.timezone }}</template> <template #timezone>{{ schedule.timezone }}</template>
</gl-sprintf> </gl-sprintf>
| {{ offset }} | {{ offset }}
<gl-dropdown right :text="formatPresetType(presetType)"> <gl-button-group data-testid="shift-preset-change">
<gl-dropdown-item <gl-button
v-for="type in $options.PRESET_TYPES" v-for="type in $options.PRESET_TYPES"
:key="type" :key="type"
:is-check-item="true" :selected="type === presetType"
:is-checked="type === presetType" :title="formatPresetType(type)"
@click="switchPresetType(type)" @click="switchPresetType(type)"
>{{ formatPresetType(type) }}</gl-dropdown-item
> >
</gl-dropdown> {{ formatPresetType(type) }}
</gl-button>
</gl-button-group>
</p> </p>
<div class="gl-w-full gl-display-flex gl-align-items-center gl-pb-3"> <div class="gl-w-full gl-display-flex gl-align-items-center gl-pb-3">
<gl-button-group> <gl-button-group>
......
<script> <script>
import { GlAlert, GlButton, GlEmptyState, GlLoadingIcon, GlModalDirective } from '@gitlab/ui'; import { GlAlert, GlButton, GlEmptyState, GlLoadingIcon, GlModalDirective } from '@gitlab/ui';
import { fetchPolicies } from '~/lib/graphql';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import * as Sentry from '~/sentry/wrapper'; import * as Sentry from '~/sentry/wrapper';
import getOncallSchedulesWithRotations from '../graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from '../graphql/queries/get_oncall_schedules.query.graphql';
import AddScheduleModal from './add_edit_schedule_modal.vue'; import AddScheduleModal from './add_edit_schedule_modal.vue';
import OncallSchedule from './oncall_schedule.vue'; import OncallSchedule from './oncall_schedule.vue';
...@@ -47,8 +46,7 @@ export default { ...@@ -47,8 +46,7 @@ export default {
}, },
apollo: { apollo: {
schedule: { schedule: {
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK, query: getOncallSchedulesWithRotationsQuery,
query: getOncallSchedulesWithRotations,
variables() { variables() {
return { return {
projectPath: this.projectPath, projectPath: this.projectPath,
......
...@@ -4,7 +4,7 @@ import { set } from 'lodash'; ...@@ -4,7 +4,7 @@ import { set } from 'lodash';
import { LENGTH_ENUM } from 'ee/oncall_schedules/constants'; import { LENGTH_ENUM } from 'ee/oncall_schedules/constants';
import createOncallScheduleRotationMutation from 'ee/oncall_schedules/graphql/mutations/create_oncall_schedule_rotation.mutation.graphql'; import createOncallScheduleRotationMutation from 'ee/oncall_schedules/graphql/mutations/create_oncall_schedule_rotation.mutation.graphql';
import updateOncallScheduleRotationMutation from 'ee/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql'; import updateOncallScheduleRotationMutation from 'ee/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql';
import getOncallSchedulesQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
import { import {
updateStoreAfterRotationAdd, updateStoreAfterRotationAdd,
updateStoreAfterRotationEdit, updateStoreAfterRotationEdit,
...@@ -152,11 +152,16 @@ export default { ...@@ -152,11 +152,16 @@ export default {
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: createOncallScheduleRotationMutation, mutation: createOncallScheduleRotationMutation,
variables: { OncallRotationCreateInput: this.rotationVariables }, variables: { input: this.rotationVariables },
update(store, { data }) { update(store, { data }) {
updateStoreAfterRotationAdd(store, getOncallSchedulesQuery, data, schedule.iid, { updateStoreAfterRotationAdd(
store,
getOncallSchedulesWithRotationsQuery,
{ ...data, scheduleIid: schedule.iid },
{
projectPath, projectPath,
}); },
);
}, },
}) })
.then( .then(
...@@ -192,11 +197,16 @@ export default { ...@@ -192,11 +197,16 @@ export default {
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: updateOncallScheduleRotationMutation, mutation: updateOncallScheduleRotationMutation,
variables: { OncallRotationUpdateInput: this.rotationVariables }, variables: { input: this.rotationVariables },
update(store, { data }) { update(store, { data }) {
updateStoreAfterRotationEdit(store, getOncallSchedulesQuery, data, schedule.iid, { updateStoreAfterRotationEdit(
store,
getOncallSchedulesWithRotationsQuery,
{ ...data, scheduleIid: schedule.iid },
{
projectPath, projectPath,
}); },
);
}, },
}) })
.then( .then(
......
...@@ -103,6 +103,7 @@ export default { ...@@ -103,6 +103,7 @@ export default {
:title="$options.i18n.editRotationLabel" :title="$options.i18n.editRotationLabel"
icon="pencil" icon="pencil"
:aria-label="$options.i18n.editRotationLabel" :aria-label="$options.i18n.editRotationLabel"
:disabled="true"
/> />
<gl-button <gl-button
v-gl-modal="$options.deleteRotationModalId" v-gl-modal="$options.deleteRotationModalId"
......
#import "../fragments/oncall_schedule_rotation.fragment.graphql" #import "../fragments/oncall_schedule_rotation.fragment.graphql"
mutation newRotation($OncallRotationCreateInput: OncallRotationCreateInput!) { mutation newRotation($input: OncallRotationCreateInput!) {
oncallRotationCreate(input: $OncallRotationCreateInput) { oncallRotationCreate(input: $input) {
errors errors
oncallRotation { oncallRotation {
...OnCallRotation ...OnCallRotation
......
#import "../fragments/oncall_schedule_rotation.fragment.graphql" #import "../fragments/oncall_schedule_rotation.fragment.graphql"
mutation updateRotation($OncallRotationUpdateInput: OncallRotationUpdateInput!) { mutation updateRotation($input: OncallRotationUpdateInput!) {
oncallRotationUpdate(input: $OncallRotationUpdateInput) { oncallRotationUpdate(input: $input) {
errors errors
oncallRotation { oncallRotation {
...OnCallRotation ...OnCallRotation
......
...@@ -8,7 +8,10 @@ import { ...@@ -8,7 +8,10 @@ import {
DELETE_ROTATION_ERROR, DELETE_ROTATION_ERROR,
} from './error_messages'; } from './error_messages';
const addScheduleToStore = (store, query, { oncallSchedule: schedule }, variables) => { const ROTATION_CONNECTION_TYPE = 'IncidentManagementOncallRotationConnection';
const addScheduleToStore = (store, query, { oncallScheduleCreate }, variables) => {
const schedule = oncallScheduleCreate?.oncallSchedule;
if (!schedule) { if (!schedule) {
return; return;
} }
...@@ -19,7 +22,10 @@ const addScheduleToStore = (store, query, { oncallSchedule: schedule }, variable ...@@ -19,7 +22,10 @@ const addScheduleToStore = (store, query, { oncallSchedule: schedule }, variable
}); });
const data = produce(sourceData, (draftData) => { const data = produce(sourceData, (draftData) => {
draftData.project.incidentManagementOncallSchedules.nodes.push(schedule); draftData.project.incidentManagementOncallSchedules.nodes.push({
...schedule,
rotations: { nodes: [], __typename: ROTATION_CONNECTION_TYPE },
});
}); });
store.writeQuery({ store.writeQuery({
...@@ -67,10 +73,11 @@ const updateScheduleFromStore = (store, query, { oncallScheduleUpdate }, variabl ...@@ -67,10 +73,11 @@ const updateScheduleFromStore = (store, query, { oncallScheduleUpdate }, variabl
const data = produce(sourceData, (draftData) => { const data = produce(sourceData, (draftData) => {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
draftData.project.incidentManagementOncallSchedules.nodes = [ draftData.project.incidentManagementOncallSchedules.nodes = draftData.project.incidentManagementOncallSchedules.nodes.map(
...draftData.project.incidentManagementOncallSchedules.nodes, (scheduleToUpdate) => {
schedule, return scheduleToUpdate.iid === schedule.iid ? schedule : scheduleToUpdate;
]; },
);
}); });
store.writeQuery({ store.writeQuery({
...@@ -80,13 +87,8 @@ const updateScheduleFromStore = (store, query, { oncallScheduleUpdate }, variabl ...@@ -80,13 +87,8 @@ const updateScheduleFromStore = (store, query, { oncallScheduleUpdate }, variabl
}); });
}; };
const addRotationToStore = ( const addRotationToStore = (store, query, { oncallRotationCreate, scheduleIid }, variables) => {
store, const rotation = oncallRotationCreate?.oncallRotation;
query,
{ oncallRotationCreate: rotation },
scheduleId,
variables,
) => {
if (!rotation) { if (!rotation) {
return; return;
} }
...@@ -96,14 +98,12 @@ const addRotationToStore = ( ...@@ -96,14 +98,12 @@ const addRotationToStore = (
variables, variables,
}); });
// TODO: This needs the rotation backend to be fully integrated to work, for the moment we will place-hold it.
const data = produce(sourceData, (draftData) => { const data = produce(sourceData, (draftData) => {
const rotations = [rotation]; const scheduleToUpdate = draftData.project.incidentManagementOncallSchedules.nodes.find(
({ iid }) => iid === scheduleIid,
);
// eslint-disable-next-line no-param-reassign scheduleToUpdate.rotations.nodes = [...scheduleToUpdate.rotations.nodes, rotation];
draftData.project.incidentManagementOncallSchedules.nodes.find(
({ iid }) => iid === scheduleId,
).rotations = rotations;
}); });
store.writeQuery({ store.writeQuery({
...@@ -113,7 +113,12 @@ const addRotationToStore = ( ...@@ -113,7 +113,12 @@ const addRotationToStore = (
}); });
}; };
const updateRotationFromStore = (store, query, { oncallRotationUpdate }, scheduleId, variables) => { const updateRotationFromStore = (
store,
query,
{ oncallRotationUpdate, scheduleIid },
variables,
) => {
const rotation = oncallRotationUpdate?.oncallRotation; const rotation = oncallRotationUpdate?.oncallRotation;
if (!rotation) { if (!rotation) {
return; return;
...@@ -125,11 +130,15 @@ const updateRotationFromStore = (store, query, { oncallRotationUpdate }, schedul ...@@ -125,11 +130,15 @@ const updateRotationFromStore = (store, query, { oncallRotationUpdate }, schedul
}); });
const data = produce(sourceData, (draftData) => { const data = produce(sourceData, (draftData) => {
// eslint-disable-next-line no-param-reassign const scheduleToUpdate = draftData.project.incidentManagementOncallSchedules.nodes.find(
draftData.project.incidentManagementOncallSchedules.nodes = [ ({ iid }) => iid === scheduleIid,
...draftData.project.incidentManagementOncallSchedules.nodes, );
rotation,
]; const updatedRotations = scheduleToUpdate.rotations.nodes.map((rotationToUpdate) => {
return rotationToUpdate.id === rotation.id ? rotation : rotationToUpdate;
});
scheduleToUpdate.rotations.nodes = updatedRotations;
}); });
store.writeQuery({ store.writeQuery({
...@@ -159,12 +168,12 @@ const deleteRotationFromStore = ( ...@@ -159,12 +168,12 @@ const deleteRotationFromStore = (
const scheduleToUpdate = draftData.project.incidentManagementOncallSchedules.nodes.find( const scheduleToUpdate = draftData.project.incidentManagementOncallSchedules.nodes.find(
({ iid }) => iid === scheduleIid, ({ iid }) => iid === scheduleIid,
); );
const updatedRotations = scheduleToUpdate.rotations?.filter(({ id }) => id !== rotation.id);
// eslint-disable-next-line no-param-reassign const updatedRotations = scheduleToUpdate.rotations.nodes.filter(
draftData.project.incidentManagementOncallSchedules.nodes.find( ({ id }) => id !== rotation.id,
({ iid }) => iid === scheduleIid, );
).rotations = updatedRotations;
scheduleToUpdate.rotations.nodes = updatedRotations;
}); });
store.writeQuery({ store.writeQuery({
...@@ -203,17 +212,17 @@ export const updateStoreAfterScheduleEdit = (store, query, data, variables) => { ...@@ -203,17 +212,17 @@ export const updateStoreAfterScheduleEdit = (store, query, data, variables) => {
} }
}; };
export const updateStoreAfterRotationAdd = (store, query, data, scheduleId, variables) => { export const updateStoreAfterRotationAdd = (store, query, data, variables) => {
if (!hasErrors(data)) { if (!hasErrors(data)) {
addRotationToStore(store, query, data, scheduleId, variables); addRotationToStore(store, query, data, variables);
} }
}; };
export const updateStoreAfterRotationEdit = (store, query, data, scheduleId, variables) => { export const updateStoreAfterRotationEdit = (store, query, data, variables) => {
if (hasErrors(data)) { if (hasErrors(data)) {
onError(data, UPDATE_ROTATION_ERROR); onError(data, UPDATE_ROTATION_ERROR);
} else { } else {
updateRotationFromStore(store, query, data, scheduleId, variables); updateRotationFromStore(store, query, data, variables);
} }
}; };
......
...@@ -7,7 +7,7 @@ import AddEditScheduleModal, { ...@@ -7,7 +7,7 @@ import AddEditScheduleModal, {
import { editScheduleModalId } from 'ee/oncall_schedules/components/oncall_schedule'; import { editScheduleModalId } from 'ee/oncall_schedules/components/oncall_schedule';
import { addScheduleModalId } from 'ee/oncall_schedules/components/oncall_schedules_wrapper'; import { addScheduleModalId } from 'ee/oncall_schedules/components/oncall_schedules_wrapper';
import updateOncallScheduleMutation from 'ee/oncall_schedules/graphql/mutations/update_oncall_schedule.mutation.graphql'; import updateOncallScheduleMutation from 'ee/oncall_schedules/graphql/mutations/update_oncall_schedule.mutation.graphql';
import getOncallSchedulesQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { import {
...@@ -71,14 +71,17 @@ describe('AddScheduleModal', () => { ...@@ -71,14 +71,17 @@ describe('AddScheduleModal', () => {
updateScheduleHandler = updateHandler; updateScheduleHandler = updateHandler;
const requestHandlers = [ const requestHandlers = [
[getOncallSchedulesQuery, jest.fn().mockResolvedValue(getOncallSchedulesQueryResponse)], [
getOncallSchedulesWithRotationsQuery,
jest.fn().mockResolvedValue(getOncallSchedulesQueryResponse),
],
[updateOncallScheduleMutation, updateScheduleHandler], [updateOncallScheduleMutation, updateScheduleHandler],
]; ];
fakeApollo = createMockApollo(requestHandlers); fakeApollo = createMockApollo(requestHandlers);
fakeApollo.clients.defaultClient.cache.writeQuery({ fakeApollo.clients.defaultClient.cache.writeQuery({
query: getOncallSchedulesQuery, query: getOncallSchedulesWithRotationsQuery,
variables: { variables: {
projectPath: 'group/project', projectPath: 'group/project',
}, },
......
...@@ -35,7 +35,7 @@ export const getOncallSchedulesQueryResponse = { ...@@ -35,7 +35,7 @@ export const getOncallSchedulesQueryResponse = {
timezone: { timezone: {
identifier: 'Pacific/Honolulu', identifier: 'Pacific/Honolulu',
}, },
rotations: { nodes: mockRotations }, rotations: { nodes: [mockRotations] },
}, },
], ],
}, },
...@@ -89,9 +89,7 @@ export const updateScheduleResponse = { ...@@ -89,9 +89,7 @@ export const updateScheduleResponse = {
name: 'Test schedule 2', name: 'Test schedule 2',
description: 'Description 2 lives here', description: 'Description 2 lives here',
timezone: 'Pacific/Honolulu', timezone: 'Pacific/Honolulu',
rotations: { rotations: { nodes: [mockRotations] },
nodes: [],
},
}, },
}, },
}, },
...@@ -107,9 +105,7 @@ export const updateScheduleResponseWithErrors = { ...@@ -107,9 +105,7 @@ export const updateScheduleResponseWithErrors = {
name: 'Test schedule 2', name: 'Test schedule 2',
description: 'Description 2 lives here', description: 'Description 2 lives here',
timezone: 'Pacific/Honolulu', timezone: 'Pacific/Honolulu',
rotations: { rotations: { nodes: [mockRotations] },
nodes: [],
},
}, },
}, },
}, },
...@@ -140,7 +136,7 @@ export const createRotationResponse = { ...@@ -140,7 +136,7 @@ export const createRotationResponse = {
oncallRotationCreate: { oncallRotationCreate: {
errors: [], errors: [],
oncallRotation: { oncallRotation: {
id: '37', id: '44',
name: 'Test', name: 'Test',
startsAt: '2020-12-17T12:00:00Z', startsAt: '2020-12-17T12:00:00Z',
length: 5, length: 5,
...@@ -173,7 +169,7 @@ export const createRotationResponseWithErrors = { ...@@ -173,7 +169,7 @@ export const createRotationResponseWithErrors = {
oncallRotationCreate: { oncallRotationCreate: {
errors: ['Houston, we have a problem'], errors: ['Houston, we have a problem'],
oncallRotation: { oncallRotation: {
id: '37', id: '44',
name: 'Test', name: 'Test',
startsAt: '2020-12-17T12:00:00Z', startsAt: '2020-12-17T12:00:00Z',
length: 5, length: 5,
......
...@@ -71,12 +71,14 @@ describe('On-call schedule', () => { ...@@ -71,12 +71,14 @@ describe('On-call schedule', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
}); });
const findScheduleHeader = () => wrapper.findByTestId('scheduleHeader'); const findScheduleHeader = () => wrapper.findByTestId('scheduleHeader');
const findRotationsHeader = () => wrapper.findByTestId('rotationsHeader'); const findRotationsHeader = () => wrapper.findByTestId('rotationsHeader');
const findSchedule = () => wrapper.findByTestId('scheduleBody'); const findSchedule = () => wrapper.findByTestId('scheduleBody');
const findRotations = () => wrapper.findByTestId('rotationsBody'); const findRotations = () => wrapper.findByTestId('rotationsBody');
const findRotationsShiftPreset = () => wrapper.findByTestId('shift-preset-change');
const findAddRotationsBtn = () => findRotationsHeader().find(GlButton); const findAddRotationsBtn = () => findRotationsHeader().find(GlButton);
const findScheduleTimeline = () => findRotations().find(ScheduleTimelineSection); const findScheduleTimeline = () => findRotations().find(ScheduleTimelineSection);
const findRotationsList = () => findRotations().find(RotationsListSection); const findRotationsList = () => findRotations().find(RotationsListSection);
...@@ -120,6 +122,25 @@ describe('On-call schedule', () => { ...@@ -120,6 +122,25 @@ describe('On-call schedule', () => {
}); });
}); });
describe('Timeframe shift preset type', () => {
it('renders rotation shift preset type buttons', () => {
expect(findRotationsShiftPreset().exists()).toBe(true);
});
it('sets shift preset type with a default type', () => {
const presetBtns = findRotationsShiftPreset().findAllComponents(GlButton);
expect(presetBtns.at(0).attributes('selected')).toBe(undefined);
expect(presetBtns.at(1).attributes('selected')).toBe('true');
});
it('updates the rotation preset type on click', async () => {
const presetBtns = findRotationsShiftPreset().findAllComponents(GlButton);
await presetBtns.at(0).vm.$emit('click');
expect(presetBtns.at(0).attributes('selected')).toBe('true');
expect(presetBtns.at(1).attributes('selected')).toBe(undefined);
});
});
describe('Timeframe update', () => { describe('Timeframe update', () => {
describe('WEEKS view', () => { describe('WEEKS view', () => {
beforeEach(() => { beforeEach(() => {
......
...@@ -6,7 +6,7 @@ import OnCallSchedule from 'ee/oncall_schedules/components/oncall_schedule.vue'; ...@@ -6,7 +6,7 @@ import OnCallSchedule from 'ee/oncall_schedules/components/oncall_schedule.vue';
import OnCallScheduleWrapper, { import OnCallScheduleWrapper, {
i18n, i18n,
} from 'ee/oncall_schedules/components/oncall_schedules_wrapper.vue'; } from 'ee/oncall_schedules/components/oncall_schedules_wrapper.vue';
import getOncallSchedulesWithRotations from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import { preExistingSchedule, newlyCreatedSchedule } from './mocks/apollo_mock'; import { preExistingSchedule, newlyCreatedSchedule } from './mocks/apollo_mock';
...@@ -44,7 +44,7 @@ describe('On-call schedule wrapper', () => { ...@@ -44,7 +44,7 @@ describe('On-call schedule wrapper', () => {
function mountComponentWithApollo() { function mountComponentWithApollo() {
const fakeApollo = createMockApollo([ const fakeApollo = createMockApollo([
[getOncallSchedulesWithRotations, getOncallSchedulesQuerySpy], [getOncallSchedulesWithRotationsQuery, getOncallSchedulesQuerySpy],
]); ]);
localVue.use(VueApollo); localVue.use(VueApollo);
...@@ -66,6 +66,7 @@ describe('On-call schedule wrapper', () => { ...@@ -66,6 +66,7 @@ describe('On-call schedule wrapper', () => {
afterEach(() => { afterEach(() => {
if (wrapper) { if (wrapper) {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
} }
}); });
......
...@@ -6,7 +6,7 @@ import AddEditRotationModal, { ...@@ -6,7 +6,7 @@ import AddEditRotationModal, {
} from 'ee/oncall_schedules/components/rotations/components/add_edit_rotation_modal.vue'; } from 'ee/oncall_schedules/components/rotations/components/add_edit_rotation_modal.vue';
import { addRotationModalId } from 'ee/oncall_schedules/constants'; import { addRotationModalId } from 'ee/oncall_schedules/constants';
import createOncallScheduleRotationMutation from 'ee/oncall_schedules/graphql/mutations/create_oncall_schedule_rotation.mutation.graphql'; import createOncallScheduleRotationMutation from 'ee/oncall_schedules/graphql/mutations/create_oncall_schedule_rotation.mutation.graphql';
import getOncallSchedulesQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql'; import getOncallSchedulesWithRotationsQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper'; import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import createFlash, { FLASH_TYPES } from '~/flash'; import createFlash, { FLASH_TYPES } from '~/flash';
...@@ -80,13 +80,16 @@ describe('AddEditRotationModal', () => { ...@@ -80,13 +80,16 @@ describe('AddEditRotationModal', () => {
localVue.use(VueApollo); localVue.use(VueApollo);
fakeApollo = createMockApollo([ fakeApollo = createMockApollo([
[getOncallSchedulesQuery, jest.fn().mockResolvedValue(getOncallSchedulesQueryResponse)], [
getOncallSchedulesWithRotationsQuery,
jest.fn().mockResolvedValue(getOncallSchedulesQueryResponse),
],
[usersSearchQuery, userSearchQueryHandler], [usersSearchQuery, userSearchQueryHandler],
[createOncallScheduleRotationMutation, createRotationHandler], [createOncallScheduleRotationMutation, createRotationHandler],
]); ]);
fakeApollo.clients.defaultClient.cache.writeQuery({ fakeApollo.clients.defaultClient.cache.writeQuery({
query: getOncallSchedulesQuery, query: getOncallSchedulesWithRotationsQuery,
variables: { variables: {
projectPath: 'group/project', projectPath: 'group/project',
}, },
...@@ -123,6 +126,7 @@ describe('AddEditRotationModal', () => { ...@@ -123,6 +126,7 @@ describe('AddEditRotationModal', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
}); });
const findModal = () => wrapper.find(GlModal); const findModal = () => wrapper.find(GlModal);
...@@ -139,7 +143,7 @@ describe('AddEditRotationModal', () => { ...@@ -139,7 +143,7 @@ describe('AddEditRotationModal', () => {
expect(mutate).toHaveBeenCalledWith({ expect(mutate).toHaveBeenCalledWith({
mutation: expect.any(Object), mutation: expect.any(Object),
update: expect.anything(), update: expect.anything(),
variables: { OncallRotationCreateInput: expect.objectContaining({ projectPath }) }, variables: { input: expect.objectContaining({ projectPath }) },
}); });
}); });
...@@ -155,7 +159,7 @@ describe('AddEditRotationModal', () => { ...@@ -155,7 +159,7 @@ describe('AddEditRotationModal', () => {
}); });
describe('with mocked Apollo client', () => { describe('with mocked Apollo client', () => {
it('it calls searchUsers query with the search paramter', async () => { it('it calls searchUsers query with the search parameter', async () => {
userSearchQueryHandler = jest.fn().mockResolvedValue({ userSearchQueryHandler = jest.fn().mockResolvedValue({
data: { data: {
users: { users: {
...@@ -168,9 +172,7 @@ describe('AddEditRotationModal', () => { ...@@ -168,9 +172,7 @@ describe('AddEditRotationModal', () => {
expect(userSearchQueryHandler).toHaveBeenCalledWith({ search: 'root' }); expect(userSearchQueryHandler).toHaveBeenCalledWith({ search: 'root' });
}); });
// Fix is coming in: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52773/ it('calls a mutation with correct parameters and creates a rotation', async () => {
// eslint-disable-next-line jest/no-disabled-tests
it.skip('calls a mutation with correct parameters and creates a rotation', async () => {
createComponentWithApollo(); createComponentWithApollo();
await createRotation(wrapper); await createRotation(wrapper);
...@@ -184,9 +186,7 @@ describe('AddEditRotationModal', () => { ...@@ -184,9 +186,7 @@ describe('AddEditRotationModal', () => {
}); });
}); });
// Fix is coming in: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52773/ it('displays alert if mutation had a recoverable error', async () => {
// eslint-disable-next-line jest/no-disabled-tests
it.skip('displays alert if mutation had a recoverable error', async () => {
createComponentWithApollo({ createComponentWithApollo({
createHandler: jest.fn().mockResolvedValue(createRotationResponseWithErrors), createHandler: jest.fn().mockResolvedValue(createRotationResponseWithErrors),
}); });
......
...@@ -109,6 +109,7 @@ describe('DeleteRotationModal', () => { ...@@ -109,6 +109,7 @@ describe('DeleteRotationModal', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
wrapper = null;
}); });
it('renders delete rotation modal layout', () => { it('renders delete rotation modal layout', () => {
...@@ -161,9 +162,7 @@ describe('DeleteRotationModal', () => { ...@@ -161,9 +162,7 @@ describe('DeleteRotationModal', () => {
expect(findModal().attributes('data-testid')).toBe(`delete-rotation-modal-${rotation.id}`); expect(findModal().attributes('data-testid')).toBe(`delete-rotation-modal-${rotation.id}`);
}); });
// Fix is coming in: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52773/ it('calls a mutation with correct parameters and destroys a rotation', async () => {
// eslint-disable-next-line jest/no-disabled-tests
it.skip('calls a mutation with correct parameters and destroys a rotation', async () => {
createComponentWithApollo(); createComponentWithApollo();
await destroyRotation(wrapper); await destroyRotation(wrapper);
...@@ -171,9 +170,7 @@ describe('DeleteRotationModal', () => { ...@@ -171,9 +170,7 @@ describe('DeleteRotationModal', () => {
expect(destroyRotationHandler).toHaveBeenCalled(); expect(destroyRotationHandler).toHaveBeenCalled();
}); });
// Fix is coming in: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52773/ it('displays alert if mutation had a recoverable error', async () => {
// eslint-disable-next-line jest/no-disabled-tests
it.skip('displays alert if mutation had a recoverable error', async () => {
createComponentWithApollo({ createComponentWithApollo({
destroyHandler: jest.fn().mockResolvedValue(destroyRotationResponseWithErrors), destroyHandler: jest.fn().mockResolvedValue(destroyRotationResponseWithErrors),
}); });
......
...@@ -22,7 +22,8 @@ exports[`RotationsListSectionComponent when the timeframe includes today renders ...@@ -22,7 +22,8 @@ exports[`RotationsListSectionComponent when the timeframe includes today renders
> >
<button <button
aria-label="Edit rotation" aria-label="Edit rotation"
class="btn btn-default btn-md gl-button btn-default-tertiary btn-icon" class="btn btn-default btn-md disabled gl-button btn-default-tertiary btn-icon"
disabled="disabled"
title="Edit rotation" title="Edit rotation"
type="button" type="button"
> >
......
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