Fix spec violations in ee/spec/frontend/test_case_show/mixins/test_case_graphql_spec.js

This spec file has some technical debt and/or antipatterns that need to be fixed before we can update our codebase to Vue3. This file may contain potential violations such as:

  • spying on methods
  • .setData() usage
  • overriding method behaviour
  • wrapper.vm or childComponent.vm modification
  • Vue.extend

Please see the related epic for more details on how these violations can be addressed.

Implementation

Sample diff
diff --git a/ee/spec/frontend/test_case_show/mixins/test_case_graphql_spec.js b/ee/spec/frontend/test_case_show/mixins/test_case_graphql_spec.js
index 4261a9d52560..197676036000 100644
--- a/ee/spec/frontend/test_case_show/mixins/test_case_graphql_spec.js
+++ b/ee/spec/frontend/test_case_show/mixins/test_case_graphql_spec.js
@@ -1,80 +1,100 @@
-import { shallowMount } from '@vue/test-utils';
-
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import createMockApollo from 'helpers/mock_apollo_helper';
 import TestCaseShowRoot from 'ee/test_case_show/components/test_case_show_root.vue';
 import IssuableShow from '~/vue_shared/issuable/show/components/issuable_show_root.vue';
+import TestCaseSidebarTodo from 'ee/test_case_show/components/test_case_sidebar_todo.vue';
 import markTestCaseTodoDone from 'ee/test_case_show/queries/mark_test_case_todo_done.mutation.graphql';
 import moveTestCase from 'ee/test_case_show/queries/move_test_case.mutation.graphql';
 import updateTestCase from 'ee/test_case_show/queries/update_test_case.mutation.graphql';
+import projectTestCase from 'ee/test_case_show/queries/project_test_case.query.graphql';
+import projectTestCaseTaskList from 'ee/test_case_show/queries/test_case_tasklist.query.graphql';
 import { mockCurrentUserTodo } from 'jest/vue_shared/issuable/list/mock_data';
 import { stubComponent } from 'helpers/stub_component';
+import waitForPromises from 'helpers/wait_for_promises';
 
 import Api from '~/api';
 import { createAlert } from '~/alert';
 import { visitUrl } from '~/lib/utils/url_utility';
 
-import { mockProvide, mockTestCase } from '../mock_data';
+import { mockProvide, mockTestCase, mockTestCaseResponse } from '../mock_data';
 
 jest.mock('~/alert');
 jest.mock('~/lib/utils/url_utility');
 
-const createComponent = ({ testCase, testCaseQueryLoading = false } = {}) =>
-  shallowMount(TestCaseShowRoot, {
-    provide: {
-      ...mockProvide,
-    },
-    mocks: {
-      $apollo: {
-        queries: {
-          testCase: {
-            loading: testCaseQueryLoading,
-            refetch: jest.fn(),
-          },
-        },
-        mutate: jest.fn(),
-      },
-    },
-    stubs: {
-      IssuableShow: stubComponent(IssuableShow),
-    },
-    data() {
-      return {
-        testCaseLoading: testCaseQueryLoading,
-        testCase: testCaseQueryLoading
-          ? {}
-          : {
-              ...mockTestCase,
-              ...testCase,
-            },
-      };
-    },
-  });
+Vue.use(VueApollo);
+const defaultRequestHandlers = {
+  markTestCaseTodoDone: jest.fn().mockResolvedValue({}),
+  moveTestCase: jest.fn().mockResolvedValue({}),
+  updateTestCase: jest.fn().mockResolvedValue({}),
+  projectTestCase: jest.fn().mockResolvedValue(mockTestCaseResponse()),
+  projectTestCaseTaskList: jest.fn().mockResolvedValue({}),
+};
 
 describe('TestCaseGraphQL Mixin', () => {
   let wrapper;
+  let requestHandlers;
+
+  const createComponent = ({ testCase, testCaseQueryLoading = false, handlers = {} } = {}) => {
+    requestHandlers = {
+      ...defaultRequestHandlers,
+      ...handlers,
+    };
+
+    wrapper = shallowMountExtended(TestCaseShowRoot, {
+      provide: {
+        ...mockProvide,
+      },
+      stubs: {
+        IssuableShow,
+      },
+      data() {
+        return {
+          testCaseLoading: testCaseQueryLoading,
+          testCase: testCaseQueryLoading
+            ? {}
+            : {
+                ...mockTestCase,
+                ...testCase,
+              },
+        };
+      },
+      apolloProvider: createMockApollo([
+        [projectTestCase, requestHandlers.projectTestCase],
+        [projectTestCaseTaskList, requestHandlers.projectTestCaseTaskList],
+        [markTestCaseTodoDone, requestHandlers.markTestCaseTodoDone],
+        [moveTestCase, requestHandlers.moveTestCase],
+        [updateTestCase, requestHandlers.updateTestCase],
+      ]),
+    });
+  };
+
+  const findSaveTestCaseButton = () => wrapper.find('[data-testid="save-test-case-button"]');
 
   beforeEach(() => {
-    wrapper = createComponent();
+    // createComponent();
   });
 
   describe('updateTestCase', () => {
-    it('calls `$apollo.mutate` with updateTestCase mutation and updateTestCaseInput variables', () => {
-      jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue({
-        data: {
-          updateIssue: {
-            errors: [],
-            issue: mockTestCase,
-          },
-        },
+    it.only('calls `$apollo.mutate` with updateTestCase mutation and updateTestCaseInput variables', async () => {
+      const updateTestCaseSpy = jest
+        .fn()
+        .mockResolvedValue({ data: { updateIssue: { errors: [], issue: mockTestCase } } });
+
+      await createComponent({ handlers: { updateTestCase: updateTestCaseSpy } });
+      await nextTick();
+      await waitForPromises();
+      await nextTick();
+      await nextTick();
+
+      debugger;
+      findSaveTestCaseButton().vm.$emit('click', {
+        issuableTitle: 'Foo',
+        issuableDescription: 'Bar',
       });
 
-      wrapper.vm.updateTestCase({
-        variables: {
-          title: 'Foo',
-        },
-        errorMessage: 'Something went wrong',
-      });
-
-      expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
+      expect(updateTestCase).toHaveBeenCalledWith({
         mutation: updateTestCase,
         variables: {
           input: {
Edited by Alexander Turinske