summaryrefslogtreecommitdiff
path: root/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
blob: 9bc14266593a5c98fe74b0ac8abf1d0ac23a32ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { GlIntersectionObserver, GlSkeletonLoader, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
import JobsApp from '~/pipelines/components/jobs/jobs_app.vue';
import JobsTable from '~/jobs/components/table/jobs_table.vue';
import getPipelineJobsQuery from '~/pipelines/graphql/queries/get_pipeline_jobs.query.graphql';
import { mockPipelineJobsQueryResponse } from '../../mock_data';

Vue.use(VueApollo);

jest.mock('~/flash');

describe('Jobs app', () => {
  let wrapper;
  let resolverSpy;

  const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
  const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon);
  const findJobsTable = () => wrapper.findComponent(JobsTable);

  const triggerInfiniteScroll = () =>
    wrapper.findComponent(GlIntersectionObserver).vm.$emit('appear');

  const createMockApolloProvider = (resolver) => {
    const requestHandlers = [[getPipelineJobsQuery, resolver]];

    return createMockApollo(requestHandlers);
  };

  const createComponent = (resolver) => {
    wrapper = shallowMount(JobsApp, {
      provide: {
        fullPath: 'root/ci-project',
        pipelineIid: 1,
      },
      apolloProvider: createMockApolloProvider(resolver),
    });
  };

  beforeEach(() => {
    resolverSpy = jest.fn().mockResolvedValue(mockPipelineJobsQueryResponse);
  });

  afterEach(() => {
    wrapper.destroy();
  });

  describe('loading spinner', () => {
    const setup = async () => {
      createComponent(resolverSpy);

      await waitForPromises();

      triggerInfiniteScroll();
    };

    it('displays loading spinner when fetching more jobs', async () => {
      await setup();

      expect(findLoadingSpinner().exists()).toBe(true);
      expect(findSkeletonLoader().exists()).toBe(false);
    });

    it('hides loading spinner after jobs have been fetched', async () => {
      await setup();
      await waitForPromises();

      expect(findLoadingSpinner().exists()).toBe(false);
      expect(findSkeletonLoader().exists()).toBe(false);
    });
  });

  it('displays the skeleton loader', () => {
    createComponent(resolverSpy);

    expect(findSkeletonLoader().exists()).toBe(true);
    expect(findJobsTable().exists()).toBe(false);
  });

  it('displays the jobs table', async () => {
    createComponent(resolverSpy);

    await waitForPromises();

    expect(findJobsTable().exists()).toBe(true);
    expect(findSkeletonLoader().exists()).toBe(false);
    expect(createAlert).not.toHaveBeenCalled();
  });

  it('handles job fetch error correctly', async () => {
    resolverSpy = jest.fn().mockRejectedValue(new Error('GraphQL error'));

    createComponent(resolverSpy);

    await waitForPromises();

    expect(createAlert).toHaveBeenCalledWith({
      message: 'An error occurred while fetching the pipelines jobs.',
    });
  });

  it('handles infinite scrolling by calling fetchMore', async () => {
    createComponent(resolverSpy);
    await waitForPromises();

    triggerInfiniteScroll();
    await waitForPromises();

    expect(resolverSpy).toHaveBeenCalledWith({
      after: 'eyJpZCI6Ijg0NyJ9',
      fullPath: 'root/ci-project',
      iid: 1,
    });
  });

  it('does not display skeleton loader again after fetchMore', async () => {
    createComponent(resolverSpy);

    expect(findSkeletonLoader().exists()).toBe(true);
    await waitForPromises();

    triggerInfiniteScroll();
    await waitForPromises();

    expect(findSkeletonLoader().exists()).toBe(false);
  });
});