summaryrefslogtreecommitdiff
path: root/spec/frontend/runner/components/runner_delete_button_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/runner/components/runner_delete_button_spec.js')
-rw-r--r--spec/frontend/runner/components/runner_delete_button_spec.js266
1 files changed, 0 insertions, 266 deletions
diff --git a/spec/frontend/runner/components/runner_delete_button_spec.js b/spec/frontend/runner/components/runner_delete_button_spec.js
deleted file mode 100644
index c8fb7a69379..00000000000
--- a/spec/frontend/runner/components/runner_delete_button_spec.js
+++ /dev/null
@@ -1,266 +0,0 @@
-import Vue from 'vue';
-import { GlButton } from '@gitlab/ui';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
-import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
-import runnerDeleteMutation from '~/runner/graphql/shared/runner_delete.mutation.graphql';
-import waitForPromises from 'helpers/wait_for_promises';
-import { captureException } from '~/runner/sentry_utils';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import { createAlert } from '~/flash';
-import { I18N_DELETE_RUNNER } from '~/runner/constants';
-
-import RunnerDeleteButton from '~/runner/components/runner_delete_button.vue';
-import RunnerDeleteModal from '~/runner/components/runner_delete_modal.vue';
-import { allRunnersData } from '../mock_data';
-
-const mockRunner = allRunnersData.data.runners.nodes[0];
-const mockRunnerId = getIdFromGraphQLId(mockRunner.id);
-
-Vue.use(VueApollo);
-
-jest.mock('~/flash');
-jest.mock('~/runner/sentry_utils');
-
-describe('RunnerDeleteButton', () => {
- let wrapper;
- let apolloProvider;
- let apolloCache;
- let runnerDeleteHandler;
-
- const findBtn = () => wrapper.findComponent(GlButton);
- const findModal = () => wrapper.findComponent(RunnerDeleteModal);
-
- const getTooltip = () => getBinding(wrapper.element, 'gl-tooltip').value;
- const getModal = () => getBinding(findBtn().element, 'gl-modal').value;
-
- const createComponent = ({ props = {}, mountFn = shallowMountExtended } = {}) => {
- const { runner, ...propsData } = props;
-
- wrapper = mountFn(RunnerDeleteButton, {
- propsData: {
- runner: {
- // We need typename so that cache.identify works
- // eslint-disable-next-line no-underscore-dangle
- __typename: mockRunner.__typename,
- id: mockRunner.id,
- shortSha: mockRunner.shortSha,
- ...runner,
- },
- ...propsData,
- },
- apolloProvider,
- directives: {
- GlTooltip: createMockDirective(),
- GlModal: createMockDirective(),
- },
- });
- };
-
- const clickOkAndWait = async () => {
- findModal().vm.$emit('primary');
- await waitForPromises();
- };
-
- beforeEach(() => {
- runnerDeleteHandler = jest.fn().mockImplementation(() => {
- return Promise.resolve({
- data: {
- runnerDelete: {
- errors: [],
- },
- },
- });
- });
- apolloProvider = createMockApollo([[runnerDeleteMutation, runnerDeleteHandler]]);
- apolloCache = apolloProvider.defaultClient.cache;
-
- jest.spyOn(apolloCache, 'evict');
- jest.spyOn(apolloCache, 'gc');
-
- createComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('Displays a delete button without an icon', () => {
- expect(findBtn().props()).toMatchObject({
- loading: false,
- icon: '',
- });
- expect(findBtn().classes('btn-icon')).toBe(false);
- expect(findBtn().text()).toBe(I18N_DELETE_RUNNER);
- });
-
- it('Displays a modal with the runner name', () => {
- expect(findModal().props('runnerName')).toBe(`#${mockRunnerId} (${mockRunner.shortSha})`);
- });
-
- it('Does not have tabindex when button is enabled', () => {
- expect(wrapper.attributes('tabindex')).toBeUndefined();
- });
-
- it('Displays a modal when clicked', () => {
- const modalId = `delete-runner-modal-${mockRunnerId}`;
-
- expect(getModal()).toBe(modalId);
- expect(findModal().attributes('modal-id')).toBe(modalId);
- });
-
- it('Does not display redundant text for screen readers', () => {
- expect(findBtn().attributes('aria-label')).toBe(undefined);
- });
-
- it('Passes other attributes to the button', () => {
- createComponent({ props: { category: 'secondary' } });
-
- expect(findBtn().props('category')).toBe('secondary');
- });
-
- describe(`Before the delete button is clicked`, () => {
- it('The mutation has not been called', () => {
- expect(runnerDeleteHandler).toHaveBeenCalledTimes(0);
- });
- });
-
- describe('Immediately after the delete button is clicked', () => {
- beforeEach(async () => {
- findModal().vm.$emit('primary');
- });
-
- it('The button has a loading state', async () => {
- expect(findBtn().props('loading')).toBe(true);
- });
-
- it('The stale tooltip is removed', async () => {
- expect(getTooltip()).toBe('');
- });
- });
-
- describe('After clicking on the delete button', () => {
- beforeEach(async () => {
- await clickOkAndWait();
- });
-
- it('The mutation to delete is called', () => {
- expect(runnerDeleteHandler).toHaveBeenCalledTimes(1);
- expect(runnerDeleteHandler).toHaveBeenCalledWith({
- input: {
- id: mockRunner.id,
- },
- });
- });
-
- it('The user can be notified with an event', () => {
- const deleted = wrapper.emitted('deleted');
-
- expect(deleted).toHaveLength(1);
- expect(deleted[0][0].message).toMatch(`#${mockRunnerId}`);
- expect(deleted[0][0].message).toMatch(`${mockRunner.shortSha}`);
- });
-
- it('evicts runner from apollo cache', () => {
- expect(apolloCache.evict).toHaveBeenCalledWith({
- id: apolloCache.identify(mockRunner),
- });
- expect(apolloCache.gc).toHaveBeenCalled();
- });
- });
-
- describe('When update fails', () => {
- describe('On a network error', () => {
- const mockErrorMsg = 'Update error!';
-
- beforeEach(async () => {
- runnerDeleteHandler.mockRejectedValueOnce(new Error(mockErrorMsg));
-
- await clickOkAndWait();
- });
-
- it('error is reported to sentry', () => {
- expect(captureException).toHaveBeenCalledWith({
- error: new Error(mockErrorMsg),
- component: 'RunnerDeleteButton',
- });
- });
-
- it('error is shown to the user', () => {
- expect(createAlert).toHaveBeenCalledTimes(1);
- });
- });
-
- describe('On a validation error', () => {
- const mockErrorMsg = 'Runner not found!';
- const mockErrorMsg2 = 'User not allowed!';
-
- beforeEach(async () => {
- runnerDeleteHandler.mockResolvedValueOnce({
- data: {
- runnerDelete: {
- errors: [mockErrorMsg, mockErrorMsg2],
- },
- },
- });
-
- await clickOkAndWait();
- });
-
- it('error is reported to sentry', () => {
- expect(captureException).toHaveBeenCalledWith({
- error: new Error(`${mockErrorMsg} ${mockErrorMsg2}`),
- component: 'RunnerDeleteButton',
- });
- });
-
- it('error is shown to the user', () => {
- expect(createAlert).toHaveBeenCalledTimes(1);
- });
-
- it('does not evict runner from apollo cache', () => {
- expect(apolloCache.evict).not.toHaveBeenCalled();
- expect(apolloCache.gc).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('When displaying a compact button for an active runner', () => {
- beforeEach(() => {
- createComponent({
- props: {
- runner: {
- active: true,
- },
- compact: true,
- },
- mountFn: mountExtended,
- });
- });
-
- it('Displays no text', () => {
- expect(findBtn().text()).toBe('');
- expect(findBtn().classes('btn-icon')).toBe(true);
- });
-
- it('Display correctly for screen readers', () => {
- expect(findBtn().attributes('aria-label')).toBe(I18N_DELETE_RUNNER);
- expect(getTooltip()).toBe(I18N_DELETE_RUNNER);
- });
-
- describe('Immediately after the button is clicked', () => {
- beforeEach(async () => {
- findModal().vm.$emit('primary');
- });
-
- it('The button has a loading state', async () => {
- expect(findBtn().props('loading')).toBe(true);
- });
-
- it('The stale tooltip is removed', async () => {
- expect(getTooltip()).toBe('');
- });
- });
- });
-});