diff --git a/config/known_invalid_graphql_queries.yml b/config/known_invalid_graphql_queries.yml
index 770366d76cf35f7dd2accab6c8f8d95a3f68e1aa..8ea9b662aa76db68d356d90950116473ec31e489 100644
--- a/config/known_invalid_graphql_queries.yml
+++ b/config/known_invalid_graphql_queries.yml
@@ -2,3 +2,4 @@
 filenames:
   - ee/app/assets/javascripts/on_demand_scans/graphql/dast_scan_create.mutation.graphql
   - ee/app/assets/javascripts/oncall_schedules/graphql/mutations/update_oncall_schedule_rotation.mutation.graphql
+  - ee/app/assets/javascripts/oncall_schedules/graphql/mutations/destroy_oncall_rotation.mutation.graphql
diff --git a/ee/app/assets/javascripts/oncall_schedules/components/rotations/components/delete_rotation_modal.vue b/ee/app/assets/javascripts/oncall_schedules/components/rotations/components/delete_rotation_modal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6bf144d307b8c60dbb2ea0e1bf15eab1571a7617
--- /dev/null
+++ b/ee/app/assets/javascripts/oncall_schedules/components/rotations/components/delete_rotation_modal.vue
@@ -0,0 +1,118 @@
+<script>
+import { isEmpty } from 'lodash';
+import { GlSprintf, GlModal, GlAlert } from '@gitlab/ui';
+import destroyOncallRotationMutation from 'ee/oncall_schedules/graphql/mutations/destroy_oncall_rotation.mutation.graphql';
+import getOncallSchedulesQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
+import { updateStoreAfterRotationDelete } from 'ee/oncall_schedules/utils/cache_updates';
+import { s__, __ } from '~/locale';
+
+export const i18n = {
+  deleteRotation: s__('OnCallSchedules|Delete rotation'),
+  deleteRotationMessage: s__(
+    'OnCallSchedules|Are you sure you want to delete the "%{deleteRotation}" rotation? This action cannot be undone.',
+  ),
+  cancel: __('Cancel'),
+};
+
+export default {
+  i18n,
+  components: {
+    GlSprintf,
+    GlModal,
+    GlAlert,
+  },
+  inject: ['projectPath'],
+  props: {
+    rotation: {
+      type: Object,
+      required: true,
+      validator: (rotation) =>
+        isEmpty(rotation) || [rotation.id, rotation.name, rotation.startsAt].every(Boolean),
+    },
+    modalId: {
+      type: String,
+      required: true,
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      error: '',
+    };
+  },
+  computed: {
+    primaryProps() {
+      return {
+        text: this.$options.i18n.deleteRotation,
+        attributes: [{ category: 'primary' }, { variant: 'danger' }, { loading: this.loading }],
+      };
+    },
+    cancelProps() {
+      return {
+        text: this.$options.i18n.cancel,
+      };
+    },
+    rotationDeleteModalTestId() {
+      return `delete-rotation-modal-${this.rotation.id}`;
+    },
+  },
+  methods: {
+    deleteRotation() {
+      const {
+        projectPath,
+        rotation: { id },
+      } = this;
+
+      this.loading = true;
+      this.$apollo
+        .mutate({
+          mutation: destroyOncallRotationMutation,
+          variables: {
+            iid: id,
+            projectPath,
+          },
+          update(store, { data }) {
+            updateStoreAfterRotationDelete(store, getOncallSchedulesQuery, data, { projectPath });
+          },
+        })
+        .then(({ data: { oncallRotationDestroy } = {} } = {}) => {
+          const error = oncallRotationDestroy.errors[0];
+          if (error) {
+            throw error;
+          }
+          this.$refs.deleteRotationModal.hide();
+        })
+        .catch((error) => {
+          this.error = error;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    hideErrorAlert() {
+      this.error = '';
+    },
+  },
+};
+</script>
+
+<template>
+  <gl-modal
+    ref="deleteRotationModal"
+    :modal-id="modalId"
+    size="sm"
+    :data-testid="rotationDeleteModalTestId"
+    :title="$options.i18n.deleteRotation"
+    :action-primary="primaryProps"
+    :action-cancel="cancelProps"
+    @primary.prevent="deleteRotation"
+    @cancel="$emit('set-rotation-to-update', {})"
+  >
+    <gl-alert v-if="error" variant="danger" class="gl-mt-n3 gl-mb-3" @dismiss="hideErrorAlert">
+      {{ error || $options.i18n.errorMsg }}
+    </gl-alert>
+    <gl-sprintf :message="$options.i18n.deleteRotationMessage">
+      <template #deleteRotation>{{ rotation.name }}</template>
+    </gl-sprintf>
+  </gl-modal>
+</template>
diff --git a/ee/app/assets/javascripts/oncall_schedules/components/schedule/components/rotations_list_section.vue b/ee/app/assets/javascripts/oncall_schedules/components/schedule/components/rotations_list_section.vue
index 9feaad8e1e340e56691bda77c1281a8e458b50b9..cbd44b6d72a9e8a4dbce43d066bbbe12217364f5 100644
--- a/ee/app/assets/javascripts/oncall_schedules/components/schedule/components/rotations_list_section.vue
+++ b/ee/app/assets/javascripts/oncall_schedules/components/schedule/components/rotations_list_section.vue
@@ -3,7 +3,8 @@ import { GlButtonGroup, GlButton, GlTooltipDirective, GlModalDirective } from '@
 import { s__ } from '~/locale';
 import CurrentDayIndicator from './current_day_indicator.vue';
 import RotationAssignee from '../../rotations/components/rotation_assignee.vue';
-import { editRotationModalId } from '../../../constants';
+import DeleteRotationModal from '../../rotations/components/delete_rotation_modal.vue';
+import { editRotationModalId, deleteRotationModalId } from '../../../constants';
 
 export const i18n = {
   editRotationLabel: s__('OnCallSchedules|Edit rotation'),
@@ -13,11 +14,13 @@ export const i18n = {
 export default {
   i18n,
   editRotationModalId,
+  deleteRotationModalId,
   components: {
     GlButtonGroup,
     GlButton,
     CurrentDayIndicator,
     RotationAssignee,
+    DeleteRotationModal,
   },
   directives: {
     GlModal: GlModalDirective,
@@ -37,6 +40,16 @@ export default {
       required: true,
     },
   },
+  data() {
+    return {
+      rotationToUpdate: {},
+    };
+  },
+  methods: {
+    setRotationToUpdate(rotation) {
+      this.rotationToUpdate = rotation;
+    },
+  },
 };
 </script>
 
@@ -61,12 +74,13 @@ export default {
             :aria-label="$options.i18n.editRotationLabel"
           />
           <gl-button
-            v-gl-modal="$options.editRotationModalId"
+            v-gl-modal="$options.deleteRotationModalId"
             v-gl-tooltip
             category="tertiary"
             :title="$options.i18n.deleteRotationLabel"
             icon="remove"
             :aria-label="$options.i18n.deleteRotationLabel"
+            @click="setRotationToUpdate(rotation)"
           />
         </gl-button-group>
       </span>
@@ -85,5 +99,10 @@ export default {
         />
       </span>
     </div>
+    <delete-rotation-modal
+      :rotation="rotationToUpdate"
+      :modal-id="$options.deleteRotationModalId"
+      @set-rotation-to-update="setRotationToUpdate"
+    />
   </div>
 </template>
diff --git a/ee/app/assets/javascripts/oncall_schedules/constants.js b/ee/app/assets/javascripts/oncall_schedules/constants.js
index 5a143d5f742a94c7770a1d26df45921f30104a9f..1f58cd1c69c181af6988b1e2fb5da1f4e56d2d98 100644
--- a/ee/app/assets/javascripts/oncall_schedules/constants.js
+++ b/ee/app/assets/javascripts/oncall_schedules/constants.js
@@ -23,3 +23,4 @@ export const PRESET_DEFAULTS = {
 
 export const addRotationModalId = 'addRotationModal';
 export const editRotationModalId = 'editRotationModal';
+export const deleteRotationModalId = 'deleteRotationModal';
diff --git a/ee/app/assets/javascripts/oncall_schedules/graphql/mutations/destroy_oncall_rotation.mutation.graphql b/ee/app/assets/javascripts/oncall_schedules/graphql/mutations/destroy_oncall_rotation.mutation.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..f42fcfc122f7452a533e0ea0b3a99e498bf5602e
--- /dev/null
+++ b/ee/app/assets/javascripts/oncall_schedules/graphql/mutations/destroy_oncall_rotation.mutation.graphql
@@ -0,0 +1,10 @@
+#import "../fragments/oncall_schedule_rotation.fragment.graphql"
+
+mutation oncallRotationDestroy($iid: String!, $projectPath: ID!) {
+  oncallRotationDestroy(input: { iid: $iid, projectPath: $projectPath }) {
+    errors
+    oncallRotation {
+      ...OnCallRotation
+    }
+  }
+}
diff --git a/ee/app/assets/javascripts/oncall_schedules/utils/cache_updates.js b/ee/app/assets/javascripts/oncall_schedules/utils/cache_updates.js
index f6c0e637e2d589f9cf9965f25540c82dfa717752..95fb60e9cdc7aac678e691566b144a16fa55d732 100644
--- a/ee/app/assets/javascripts/oncall_schedules/utils/cache_updates.js
+++ b/ee/app/assets/javascripts/oncall_schedules/utils/cache_updates.js
@@ -5,6 +5,7 @@ import {
   DELETE_SCHEDULE_ERROR,
   UPDATE_SCHEDULE_ERROR,
   UPDATE_ROTATION_ERROR,
+  DELETE_ROTATION_ERROR,
 } from './error_messages';
 
 const addScheduleToStore = (store, query, { oncallSchedule: schedule }, variables) => {
@@ -138,6 +139,32 @@ const updateRotationFromStore = (store, query, { oncallRotationUpdate }, schedul
   });
 };
 
+const deleteRotationFromStore = (store, query, { oncallRotationDestroy }, variables) => {
+  const rotation = oncallRotationDestroy?.oncallRotation;
+  if (!rotation) {
+    return;
+  }
+
+  const sourceData = store.readQuery({
+    query,
+    variables,
+  });
+
+  // TODO: This needs the rotation backend to be fully integrated to work, for the moment we will place-hold it. https://gitlab.com/gitlab-org/gitlab/-/issues/262863
+  const data = produce(sourceData, (draftData) => {
+    // eslint-disable-next-line no-param-reassign
+    draftData.project.incidentManagementOncallSchedules.nodes[0].rotations = [rotation].filter(
+      ({ id }) => id !== rotation.id,
+    );
+  });
+
+  store.writeQuery({
+    query,
+    variables,
+    data,
+  });
+};
+
 const onError = (data, message) => {
   createFlash({ message });
   throw new Error(data.errors);
@@ -180,3 +207,11 @@ export const updateStoreAfterRotationEdit = (store, query, data, scheduleId, var
     updateRotationFromStore(store, query, data, scheduleId, variables);
   }
 };
+
+export const updateStoreAfterRotationDelete = (store, query, data, variables) => {
+  if (hasErrors(data)) {
+    onError(data, DELETE_ROTATION_ERROR);
+  } else {
+    deleteRotationFromStore(store, query, data, variables);
+  }
+};
diff --git a/ee/app/assets/javascripts/oncall_schedules/utils/error_messages.js b/ee/app/assets/javascripts/oncall_schedules/utils/error_messages.js
index 158ec951cb91a4833854df51d1eb63b50b7f4076..67d3ebb06bb8c7e730af6cd205630d220b76cfcd 100644
--- a/ee/app/assets/javascripts/oncall_schedules/utils/error_messages.js
+++ b/ee/app/assets/javascripts/oncall_schedules/utils/error_messages.js
@@ -11,3 +11,7 @@ export const UPDATE_SCHEDULE_ERROR = s__(
 export const UPDATE_ROTATION_ERROR = s__(
   'OnCallSchedules|The rotation could not be updated. Please try again.',
 );
+
+export const DELETE_ROTATION_ERROR = s__(
+  'OnCallSchedules|The rotation could not be deleted. Please try again.',
+);
diff --git a/ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js b/ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js
index 9fbbfbb66216ce4a7fb1b63f4761d67fa0f66cbb..3dc0d706fdc24fc2b3070338223c7bc356bc5170 100644
--- a/ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js
+++ b/ee/spec/frontend/oncall_schedule/add_edit_schedule_form_spec.js
@@ -47,7 +47,6 @@ describe('AddEditScheduleForm', () => {
 
   afterEach(() => {
     wrapper.destroy();
-    wrapper = null;
   });
 
   const findTimezoneDropdown = () => wrapper.find(GlDropdown);
diff --git a/ee/spec/frontend/oncall_schedule/delete_schedule_modal_spec.js b/ee/spec/frontend/oncall_schedule/delete_schedule_modal_spec.js
index f5d15bb403b5bd73898c9ef383606f243b9e30af..93b5c9947f5ae5a593490c6f4320b2074124e37f 100644
--- a/ee/spec/frontend/oncall_schedule/delete_schedule_modal_spec.js
+++ b/ee/spec/frontend/oncall_schedule/delete_schedule_modal_spec.js
@@ -22,8 +22,6 @@ const mockHideModal = jest.fn();
 const schedule =
   getOncallSchedulesQueryResponse.data.project.incidentManagementOncallSchedules.nodes[0];
 
-localVue.use(VueApollo);
-
 describe('DeleteScheduleModal', () => {
   let wrapper;
   let fakeApollo;
@@ -40,9 +38,6 @@ describe('DeleteScheduleModal', () => {
   }
 
   async function destroySchedule(localWrapper) {
-    await jest.runOnlyPendingTimers();
-    await localWrapper.vm.$nextTick();
-
     localWrapper.find(GlModal).vm.$emit('primary', { preventDefault: jest.fn() });
   }
 
@@ -111,7 +106,6 @@ describe('DeleteScheduleModal', () => {
 
   afterEach(() => {
     wrapper.destroy();
-    wrapper = null;
   });
 
   it('renders delete schedule modal layout', () => {
diff --git a/ee/spec/frontend/oncall_schedule/mocks/apollo_mock.js b/ee/spec/frontend/oncall_schedule/mocks/apollo_mock.js
index c0a23d02d35c56d62ad050b3aecff8f3c954b195..04278fd03f6d1b610fd219ad941f3680dbe0be7b 100644
--- a/ee/spec/frontend/oncall_schedule/mocks/apollo_mock.js
+++ b/ee/spec/frontend/oncall_schedule/mocks/apollo_mock.js
@@ -1,3 +1,5 @@
+import mockRotations from './mock_rotation.json';
+
 export const participants = [
   {
     id: '1',
@@ -165,3 +167,27 @@ export const createRotationResponseWithErrors = {
     },
   },
 };
+
+export const destroyRotationResponse = {
+  data: {
+    oncallRotationDestroy: {
+      errors: [],
+      oncallRotation: {
+        __typename: 'IncidentManagementOncallRotation',
+        ...mockRotations[0],
+      },
+    },
+  },
+};
+
+export const destroyRotationResponseWithErrors = {
+  data: {
+    oncallRotationDestroy: {
+      errors: ['Houston, we have a problem'],
+      oncallRotation: {
+        __typename: 'IncidentManagementOncallRotation',
+        ...mockRotations[0],
+      },
+    },
+  },
+};
diff --git a/ee/spec/frontend/oncall_schedule/oncall_schedule_spec.js b/ee/spec/frontend/oncall_schedule/oncall_schedule_spec.js
index f70081f0bc6e650a950fe63b0f28e66f9198881d..9fd2c4e72c3ea16804d7f9e061c69855c0f4fab7 100644
--- a/ee/spec/frontend/oncall_schedule/oncall_schedule_spec.js
+++ b/ee/spec/frontend/oncall_schedule/oncall_schedule_spec.js
@@ -22,7 +22,7 @@ describe('On-call schedule', () => {
   const mockWeeksTimeFrame = ['31 Dec 2020', '7 Jan 2021', '14 Jan 2021'];
   const formattedTimezone = '(UTC-09:00) AKST Alaska';
 
-  function mountComponent({ schedule } = {}) {
+  function createComponent({ schedule } = {}) {
     wrapper = extendedWrapper(
       shallowMount(OnCallSchedule, {
         propsData: {
@@ -42,12 +42,11 @@ describe('On-call schedule', () => {
   beforeEach(() => {
     jest.spyOn(utils, 'getTimeframeForWeeksView').mockReturnValue(mockWeeksTimeFrame);
     jest.spyOn(commonUtils, 'getFormattedTimezone').mockReturnValue(formattedTimezone);
-    mountComponent({ schedule: mockSchedule });
+    createComponent({ schedule: mockSchedule });
   });
 
   afterEach(() => {
     wrapper.destroy();
-    wrapper = null;
   });
 
   const findScheduleHeader = () => wrapper.findByTestId('scheduleHeader');
diff --git a/ee/spec/frontend/oncall_schedule/rotations/components/__snapshots__/delete_rotation_modal_spec.js.snap b/ee/spec/frontend/oncall_schedule/rotations/components/__snapshots__/delete_rotation_modal_spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..c7b077d454f0a4924ebab57418ef546fd28bc673
--- /dev/null
+++ b/ee/spec/frontend/oncall_schedule/rotations/components/__snapshots__/delete_rotation_modal_spec.js.snap
@@ -0,0 +1,20 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DeleteRotationModal renders delete rotation modal layout 1`] = `
+<gl-modal-stub
+  actioncancel="[object Object]"
+  actionprimary="[object Object]"
+  data-testid="delete-rotation-modal-gid://gitlab/IncidentManagement::OncallRotation/2"
+  modalclass=""
+  modalid="deleteRotationModal"
+  size="sm"
+  title="Delete rotation"
+  titletag="h4"
+>
+  <!---->
+   
+  <gl-sprintf-stub
+    message="Are you sure you want to delete the \\"%{deleteRotation}\\" rotation? This action cannot be undone."
+  />
+</gl-modal-stub>
+`;
diff --git a/ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_modal_spec.js b/ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_modal_spec.js
index 2490e7a22e91d345a253f67fa12d38048bfb89df..f3969552fbadce2620cf6be5d942326b7281d06d 100644
--- a/ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_modal_spec.js
+++ b/ee/spec/frontend/oncall_schedule/rotations/components/add_edit_rotation_modal_spec.js
@@ -123,7 +123,6 @@ describe('AddEditRotationModal', () => {
 
   afterEach(() => {
     wrapper.destroy();
-    wrapper = null;
   });
 
   const findModal = () => wrapper.find(GlModal);
diff --git a/ee/spec/frontend/oncall_schedule/rotations/components/delete_rotation_modal_spec.js b/ee/spec/frontend/oncall_schedule/rotations/components/delete_rotation_modal_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..d4bd49ae40b8236d4f6d609eb419712cba9f7291
--- /dev/null
+++ b/ee/spec/frontend/oncall_schedule/rotations/components/delete_rotation_modal_spec.js
@@ -0,0 +1,182 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import createMockApollo from 'jest/helpers/mock_apollo_helper';
+import { GlModal, GlAlert, GlSprintf } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
+import waitForPromises from 'helpers/wait_for_promises';
+import getOncallSchedulesQuery from 'ee/oncall_schedules/graphql/queries/get_oncall_schedules.query.graphql';
+import destroyOncallRotationMutation from 'ee/oncall_schedules/graphql/mutations/destroy_oncall_rotation.mutation.graphql';
+import DeleteRotationModal, {
+  i18n,
+} from 'ee/oncall_schedules/components/rotations/components/delete_rotation_modal.vue';
+import { deleteRotationModalId } from 'ee/oncall_schedules/constants';
+import {
+  getOncallSchedulesQueryResponse,
+  destroyRotationResponse,
+  destroyRotationResponseWithErrors,
+} from '../../mocks/apollo_mock';
+import mockRotations from '../../mocks/mock_rotation.json';
+
+const localVue = createLocalVue();
+const projectPath = 'group/project';
+const mutate = jest.fn();
+const mockHideModal = jest.fn();
+const rotation = mockRotations[0];
+
+describe('DeleteRotationModal', () => {
+  let wrapper;
+  let fakeApollo;
+  let destroyRotationHandler;
+
+  const findModal = () => wrapper.find(GlModal);
+  const findModalText = () => wrapper.find(GlSprintf);
+  const findAlert = () => wrapper.find(GlAlert);
+
+  async function awaitApolloDomMock() {
+    await wrapper.vm.$nextTick(); // kick off the DOM update
+    await jest.runOnlyPendingTimers(); // kick off the mocked GQL stuff (promises)
+    await wrapper.vm.$nextTick(); // kick off the DOM update
+  }
+
+  async function destroyRotation(localWrapper) {
+    localWrapper.find(GlModal).vm.$emit('primary', { preventDefault: jest.fn() });
+  }
+
+  const createComponent = ({ data = {}, props = {} } = {}) => {
+    wrapper = shallowMount(DeleteRotationModal, {
+      data() {
+        return {
+          ...data,
+        };
+      },
+      propsData: {
+        modalId: deleteRotationModalId,
+        rotation,
+        ...props,
+      },
+      provide: {
+        projectPath,
+      },
+      mocks: {
+        $apollo: {
+          mutate,
+        },
+      },
+      stubs: { GlSprintf: false },
+    });
+    wrapper.vm.$refs.deleteRotationModal.hide = mockHideModal;
+  };
+
+  function createComponentWithApollo({
+    destroyHandler = jest.fn().mockResolvedValue(destroyRotationResponse),
+  } = {}) {
+    localVue.use(VueApollo);
+    destroyRotationHandler = destroyHandler;
+
+    const requestHandlers = [
+      [getOncallSchedulesQuery, jest.fn().mockResolvedValue(getOncallSchedulesQueryResponse)],
+      [destroyOncallRotationMutation, destroyRotationHandler],
+    ];
+
+    fakeApollo = createMockApollo(requestHandlers);
+
+    fakeApollo.clients.defaultClient.cache.writeQuery({
+      query: getOncallSchedulesQuery,
+      variables: {
+        projectPath: 'group/project',
+      },
+      data: getOncallSchedulesQueryResponse.data,
+    });
+
+    wrapper = shallowMount(DeleteRotationModal, {
+      localVue,
+      apolloProvider: fakeApollo,
+      propsData: {
+        rotation,
+        modalId: deleteRotationModalId,
+      },
+      provide: {
+        projectPath,
+      },
+    });
+  }
+
+  beforeEach(() => {
+    createComponent();
+  });
+
+  afterEach(() => {
+    wrapper.destroy();
+  });
+
+  it('renders delete rotation modal layout', () => {
+    expect(wrapper.element).toMatchSnapshot();
+  });
+
+  describe('renders delete modal with the correct rotation information', () => {
+    it('renders name of rotation to destroy', () => {
+      expect(findModalText().attributes('message')).toBe(i18n.deleteRotationMessage);
+    });
+  });
+
+  describe('Rotation destroy apollo API call', () => {
+    it('makes a request with `oncallRotationDestroy` to delete a rotation', () => {
+      mutate.mockResolvedValueOnce({});
+      findModal().vm.$emit('primary', { preventDefault: jest.fn() });
+      expect(mutate).toHaveBeenCalledWith({
+        mutation: expect.any(Object),
+        update: expect.anything(),
+        variables: { iid: rotation.id, projectPath },
+      });
+    });
+
+    it('hides the modal on successful rotation deletion', async () => {
+      mutate.mockResolvedValueOnce({ data: { oncallRotationDestroy: { errors: [] } } });
+      findModal().vm.$emit('primary', { preventDefault: jest.fn() });
+      await waitForPromises();
+      expect(mockHideModal).toHaveBeenCalled();
+    });
+
+    it('does not hide the modal on deletion fail and shows the error alert', async () => {
+      const error = 'some error';
+      mutate.mockResolvedValueOnce({ data: { oncallRotationDestroy: { errors: [error] } } });
+      findModal().vm.$emit('primary', { preventDefault: jest.fn() });
+      await waitForPromises();
+      const alert = findAlert();
+      expect(mockHideModal).not.toHaveBeenCalled();
+      expect(alert.exists()).toBe(true);
+      expect(alert.text()).toContain(error);
+    });
+  });
+
+  describe('with mocked Apollo client', () => {
+    it('has the name of the rotation to delete based on getOncallSchedulesQuery', async () => {
+      createComponentWithApollo();
+
+      await jest.runOnlyPendingTimers();
+      await wrapper.vm.$nextTick();
+
+      expect(findModal().attributes('data-testid')).toBe(`delete-rotation-modal-${rotation.id}`);
+    });
+
+    it('calls a mutation with correct parameters and destroys a rotation', async () => {
+      createComponentWithApollo();
+
+      await destroyRotation(wrapper);
+
+      expect(destroyRotationHandler).toHaveBeenCalled();
+    });
+
+    it('displays alert if mutation had a recoverable error', async () => {
+      createComponentWithApollo({
+        destroyHandler: jest.fn().mockResolvedValue(destroyRotationResponseWithErrors),
+      });
+
+      await destroyRotation(wrapper);
+      await awaitApolloDomMock();
+
+      const alert = findAlert();
+      expect(alert.exists()).toBe(true);
+      expect(alert.text()).toContain('Houston, we have a problem');
+    });
+  });
+});
diff --git a/ee/spec/frontend/oncall_schedule/rotations/components/rotation_assignee_spec.js b/ee/spec/frontend/oncall_schedule/rotations/components/rotation_assignee_spec.js
index 8367454d56ddcfc883ed7b306b2d9c57a7b8184e..e4d6264ccf62a6b8fc78dff61b30d662fa5a7595 100644
--- a/ee/spec/frontend/oncall_schedule/rotations/components/rotation_assignee_spec.js
+++ b/ee/spec/frontend/oncall_schedule/rotations/components/rotation_assignee_spec.js
@@ -14,7 +14,7 @@ describe('RotationAssignee', () => {
   const findStartsAt = () => wrapper.findByTestId('rotation-assignee-starts-at');
   const findEndsAt = () => wrapper.findByTestId('rotation-assignee-ends-at');
 
-  function mountComponent() {
+  function createComponent() {
     wrapper = extendedWrapper(
       shallowMount(RotationAssignee, {
         propsData: {
@@ -28,12 +28,11 @@ describe('RotationAssignee', () => {
   }
 
   beforeEach(() => {
-    mountComponent();
+    createComponent();
   });
 
   afterEach(() => {
     wrapper.destroy();
-    wrapper = null;
   });
 
   describe('rotation assignee token', () => {
diff --git a/ee/spec/frontend/oncall_schedule/schedule/components/__snapshots__/rotations_list_section_spec.js.snap b/ee/spec/frontend/oncall_schedule/schedule/components/__snapshots__/rotations_list_section_spec.js.snap
index 7ba7f07b6bc52a3467f78bf276f5a94c84b7a46e..e1e42512198bcddfd30951abe2e53d5da788b062 100644
--- a/ee/spec/frontend/oncall_schedule/schedule/components/__snapshots__/rotations_list_section_spec.js.snap
+++ b/ee/spec/frontend/oncall_schedule/schedule/components/__snapshots__/rotations_list_section_spec.js.snap
@@ -78,5 +78,10 @@ exports[`RotationsListSectionComponent renders component layout 1`] = `
       />
     </span>
   </div>
+   
+  <delete-rotation-modal-stub
+    modalid="deleteRotationModal"
+    rotation="[object Object]"
+  />
 </div>
 `;
diff --git a/ee/spec/frontend/oncall_schedule/schedule/components/current_day_indicator_spec.js b/ee/spec/frontend/oncall_schedule/schedule/components/current_day_indicator_spec.js
index 6fb7837644510e1203adf29fa7b289ff70dbcc3f..e6fced920d1d04acd65321ec039ff6cde52def5b 100644
--- a/ee/spec/frontend/oncall_schedule/schedule/components/current_day_indicator_spec.js
+++ b/ee/spec/frontend/oncall_schedule/schedule/components/current_day_indicator_spec.js
@@ -12,7 +12,7 @@ describe('CurrentDayIndicator', () => {
   // current indicator will be rendered
   const mockTimeframeInitialDate = new Date(2018, 0, 1);
 
-  function mountComponent() {
+  function createComponent() {
     wrapper = shallowMount(CurrentDayIndicator, {
       propsData: {
         presetType: PRESET_TYPES.WEEKS,
@@ -22,13 +22,12 @@ describe('CurrentDayIndicator', () => {
   }
 
   beforeEach(() => {
-    mountComponent();
+    createComponent();
   });
 
   afterEach(() => {
     if (wrapper) {
       wrapper.destroy();
-      wrapper = null;
     }
   });
 
diff --git a/ee/spec/frontend/oncall_schedule/schedule/components/rotations_list_section_spec.js b/ee/spec/frontend/oncall_schedule/schedule/components/rotations_list_section_spec.js
index 68ee03a275be5cd37f4d47993e7a66cd7fac5425..ce9f50fda6e8511faaf0304c331757f8bd572e0f 100644
--- a/ee/spec/frontend/oncall_schedule/schedule/components/rotations_list_section_spec.js
+++ b/ee/spec/frontend/oncall_schedule/schedule/components/rotations_list_section_spec.js
@@ -12,7 +12,7 @@ describe('RotationsListSectionComponent', () => {
   const mockTimeframeInitialDate = new Date(2018, 0, 1);
   const mockTimeframeWeeks = getTimeframeForWeeksView(mockTimeframeInitialDate);
 
-  function mountComponent({
+  function createComponent({
     presetType = PRESET_TYPES.WEEKS,
     timeframe = mockTimeframeWeeks,
   } = {}) {
@@ -29,13 +29,12 @@ describe('RotationsListSectionComponent', () => {
   }
 
   beforeEach(() => {
-    mountComponent();
+    createComponent();
   });
 
   afterEach(() => {
     if (wrapper) {
       wrapper.destroy();
-      wrapper = null;
     }
   });
 
diff --git a/ee/spec/frontend/oncall_schedule/schedule/components/schedule_timeline_section_spec.js b/ee/spec/frontend/oncall_schedule/schedule/components/schedule_timeline_section_spec.js
index 955c8d9c0fe5c0abda435e4ee34b9805cbd393b1..d15473679cb0c6d562db98c179d9a2c6e95c2a0f 100644
--- a/ee/spec/frontend/oncall_schedule/schedule/components/schedule_timeline_section_spec.js
+++ b/ee/spec/frontend/oncall_schedule/schedule/components/schedule_timeline_section_spec.js
@@ -12,7 +12,7 @@ describe('TimelineSectionComponent', () => {
   const schedule =
     getOncallSchedulesQueryResponse.data.project.incidentManagementOncallSchedules.nodes[0];
 
-  function mountComponent({
+  function createComponent({
     presetType = PRESET_TYPES.WEEKS,
     timeframe = mockTimeframeWeeks,
   } = {}) {
@@ -26,12 +26,11 @@ describe('TimelineSectionComponent', () => {
   }
 
   beforeEach(() => {
-    mountComponent({});
+    createComponent();
   });
 
   afterEach(() => {
     wrapper.destroy();
-    wrapper = null;
   });
 
   it('renders component container element with class `timeline-section`', () => {
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index bba8eed23ec0e5f3a87f9507ffc44aa2a618b346..f88575673b64ec9f6e9760c2f5c849d7a7d22403 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -19526,6 +19526,9 @@ msgstr ""
 msgid "OnCallSchedules|Add schedule"
 msgstr ""
 
+msgid "OnCallSchedules|Are you sure you want to delete the \"%{deleteRotation}\" rotation? This action cannot be undone."
+msgstr ""
+
 msgid "OnCallSchedules|Are you sure you want to delete the \"%{deleteSchedule}\" schedule? This action cannot be undone."
 msgstr ""
 
@@ -19592,6 +19595,9 @@ msgstr ""
 msgid "OnCallSchedules|Successfully edited your rotation"
 msgstr ""
 
+msgid "OnCallSchedules|The rotation could not be deleted. Please try again."
+msgstr ""
+
 msgid "OnCallSchedules|The rotation could not be updated. Please try again."
 msgstr ""