From 5f645672078ff627295e8ce5f32b9024c1f68dd3 Mon Sep 17 00:00:00 2001
From: Alex Pennells <apennells@gitlab.com>
Date: Tue, 16 May 2023 09:23:59 -0400
Subject: [PATCH] Convert ThroughputChart tests to createMockApollo

Stop directly modifying the Vue data and instead mock the
GraphQL that the component receives.
---
 .../components/throughput_chart_spec.js       | 76 +++++++++----------
 .../merge_request_analytics/mock_data.js      |  3 +
 2 files changed, 37 insertions(+), 42 deletions(-)

diff --git a/ee/spec/frontend/analytics/merge_request_analytics/components/throughput_chart_spec.js b/ee/spec/frontend/analytics/merge_request_analytics/components/throughput_chart_spec.js
index 6cd6b80652515..741860e4a778c 100644
--- a/ee/spec/frontend/analytics/merge_request_analytics/components/throughput_chart_spec.js
+++ b/ee/spec/frontend/analytics/merge_request_analytics/components/throughput_chart_spec.js
@@ -3,8 +3,12 @@ import { GlAreaChart } from '@gitlab/ui/dist/charts';
 import { shallowMount } from '@vue/test-utils';
 import Vue, { nextTick } from 'vue';
 import Vuex from 'vuex';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
 import ThroughputChart from 'ee/analytics/merge_request_analytics/components/throughput_chart.vue';
 import ThroughputStats from 'ee/analytics/merge_request_analytics/components/throughput_stats.vue';
+import throughputChartQueryBuilder from 'ee/analytics/merge_request_analytics/graphql/throughput_chart_query_builder';
 import { THROUGHPUT_CHART_STRINGS } from 'ee/analytics/merge_request_analytics/constants';
 import store from 'ee/analytics/merge_request_analytics/store';
 import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleton_loader.vue';
@@ -17,7 +21,9 @@ import {
 } from '../mock_data';
 
 Vue.use(Vuex);
+Vue.use(VueApollo);
 
+const defaultQueryResolver = jest.fn().mockResolvedValue({ data: { throughputChartData: [] } });
 const defaultQueryVariables = {
   assigneeUsername: null,
   authorUsername: null,
@@ -25,14 +31,6 @@ const defaultQueryVariables = {
   labels: null,
 };
 
-const defaultMocks = {
-  $apollo: {
-    queries: {
-      throughputChartData: {},
-    },
-  },
-};
-
 describe('ThroughputChart', () => {
   let wrapper;
 
@@ -42,15 +40,17 @@ describe('ThroughputChart', () => {
     expect(element.exists()).toBe(visible);
   }
 
-  function createComponent(options = {}) {
-    const { mocks = defaultMocks } = options;
-    return shallowMount(ThroughputChart, {
+  function createWrapper({ queryResolver = null } = {}) {
+    const query = throughputChartQueryBuilder(startDate, endDate);
+    const apolloProvider = createMockApollo([[query, queryResolver || defaultQueryResolver]]);
+
+    wrapper = shallowMount(ThroughputChart, {
       store,
-      mocks,
+      apolloProvider,
       provide: {
         fullPath,
       },
-      props: {
+      propsData: {
         startDate,
         endDate,
       },
@@ -58,8 +58,9 @@ describe('ThroughputChart', () => {
   }
 
   describe('default state', () => {
-    beforeEach(() => {
-      wrapper = createComponent();
+    beforeEach(async () => {
+      createWrapper();
+      await waitForPromises();
     });
 
     it('displays the throughput stats component', () => {
@@ -80,7 +81,6 @@ describe('ThroughputChart', () => {
 
     it('displays an empty state message when there is no data', () => {
       const alert = wrapper.findComponent(GlAlert);
-
       expect(alert.exists()).toBe(true);
       expect(alert.text()).toBe(THROUGHPUT_CHART_STRINGS.NO_DATA);
     });
@@ -95,16 +95,8 @@ describe('ThroughputChart', () => {
   });
 
   describe('while loading', () => {
-    const apolloLoading = {
-      queries: {
-        throughputChartData: {
-          loading: true,
-        },
-      },
-    };
-
     beforeEach(() => {
-      wrapper = createComponent({ mocks: { ...defaultMocks, $apollo: apolloLoading } });
+      createWrapper();
     });
 
     it('displays a skeleton loader', () => {
@@ -121,11 +113,10 @@ describe('ThroughputChart', () => {
   });
 
   describe('with data', () => {
-    beforeEach(() => {
-      wrapper = createComponent();
-      // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
-      // eslint-disable-next-line no-restricted-syntax
-      wrapper.setData({ throughputChartData });
+    beforeEach(async () => {
+      const queryResolver = jest.fn().mockResolvedValue({ data: { throughputChartData } });
+      createWrapper({ queryResolver });
+      await waitForPromises();
     });
 
     it('displays the chart', () => {
@@ -142,11 +133,12 @@ describe('ThroughputChart', () => {
   });
 
   describe('with no data in the response', () => {
-    beforeEach(() => {
-      wrapper = createComponent();
-      // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
-      // eslint-disable-next-line no-restricted-syntax
-      wrapper.setData({ throughputChartData: throughputChartNoData });
+    beforeEach(async () => {
+      const queryResolver = jest
+        .fn()
+        .mockResolvedValue({ data: { throughputChartData: throughputChartNoData } });
+      createWrapper({ queryResolver });
+      await waitForPromises();
     });
 
     it('does not display a skeleton loader', () => {
@@ -166,11 +158,10 @@ describe('ThroughputChart', () => {
   });
 
   describe('with errors', () => {
-    beforeEach(() => {
-      wrapper = createComponent();
-      // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
-      // eslint-disable-next-line no-restricted-syntax
-      wrapper.setData({ hasError: true });
+    beforeEach(async () => {
+      const queryResolver = jest.fn().mockRejectedValue();
+      createWrapper({ queryResolver });
+      await waitForPromises();
     });
 
     it('does not display the chart', () => {
@@ -190,8 +181,9 @@ describe('ThroughputChart', () => {
   });
 
   describe('when fetching data', () => {
-    beforeEach(() => {
-      wrapper = createComponent();
+    beforeEach(async () => {
+      createWrapper();
+      await waitForPromises();
     });
 
     it('has initial variables set', () => {
diff --git a/ee/spec/frontend/analytics/merge_request_analytics/mock_data.js b/ee/spec/frontend/analytics/merge_request_analytics/mock_data.js
index 7a43485bac5d3..99615ee48714e 100644
--- a/ee/spec/frontend/analytics/merge_request_analytics/mock_data.js
+++ b/ee/spec/frontend/analytics/merge_request_analytics/mock_data.js
@@ -11,6 +11,7 @@ export const throughputChartData = {
   May_2020: { count: 2, totalTimeToMerge: 1234567, __typename: 'MergeRequestConnection' },
   Jun_2020: { count: 4, totalTimeToMerge: 2345678, __typename: 'MergeRequestConnection' },
   Jul_2020: { count: 3, totalTimeToMerge: 3456789, __typename: 'MergeRequestConnection' },
+  Aug_2020: { count: 4, totalTimeToMerge: 3456789, __typename: 'MergeRequestConnection' },
   __typename: 'Project',
 };
 
@@ -18,6 +19,7 @@ export const throughputChartNoData = {
   May_2020: { count: 0, totalTimeToMerge: 0, __typename: 'MergeRequestConnection' },
   Jun_2020: { count: 0, totalTimeToMerge: 0, __typename: 'MergeRequestConnection' },
   Jul_2020: { count: 0, totalTimeToMerge: 0, __typename: 'MergeRequestConnection' },
+  Aug_2020: { count: 0, totalTimeToMerge: 0, __typename: 'MergeRequestConnection' },
   __typename: 'Project',
 };
 
@@ -27,6 +29,7 @@ export const formattedThroughputChartData = [
       ['May 2020', 2],
       ['Jun 2020', 4],
       ['Jul 2020', 3],
+      ['Aug 2020', 4],
     ],
     name: THROUGHPUT_CHART_STRINGS.Y_AXIS_TITLE,
   },
-- 
GitLab