Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mr_widget_terraform_container_spec.js « terraform « components « vue_merge_request_widget « frontend « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8f20d6a8fc93645f19e187a04d48c5a2005099d2 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import { GlSkeletonLoader, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
import axios from '~/lib/utils/axios_utils';
import Poll from '~/lib/utils/poll';
import MrWidgetExpanableSection from '~/vue_merge_request_widget/components/mr_widget_expandable_section.vue';
import MrWidgetTerraformContainer from '~/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue';
import TerraformPlan from '~/vue_merge_request_widget/components/terraform/terraform_plan.vue';
import { invalidPlanWithName, plans, validPlanWithName } from './mock_data';

describe('MrWidgetTerraformConainer', () => {
  let mock;
  let wrapper;

  const propsData = { endpoint: '/path/to/terraform/report.json' };

  const findHeader = () => wrapper.find('[data-testid="terraform-header-text"]');
  const findPlans = () => wrapper.findAll(TerraformPlan).wrappers.map((x) => x.props('plan'));

  const mockPollingApi = (response, body, header) => {
    mock.onGet(propsData.endpoint).reply(response, body, header);
  };

  const mountWrapper = () => {
    wrapper = shallowMount(MrWidgetTerraformContainer, {
      propsData,
      stubs: { MrWidgetExpanableSection, GlSprintf },
    });
    return axios.waitForAll();
  };

  beforeEach(() => {
    mock = new MockAdapter(axios);
  });

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

  describe('when data is loading', () => {
    beforeEach(async () => {
      mockPollingApi(200, plans, {});

      await mountWrapper();
      // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
      // eslint-disable-next-line no-restricted-syntax
      wrapper.setData({ loading: true });
      await nextTick();
    });

    it('diplays loading skeleton', () => {
      expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(true);
      expect(wrapper.find(MrWidgetExpanableSection).exists()).toBe(false);
    });
  });

  describe('when data has finished loading', () => {
    beforeEach(() => {
      mockPollingApi(200, plans, {});
      return mountWrapper();
    });

    it('displays terraform content', () => {
      expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(false);
      expect(wrapper.find(MrWidgetExpanableSection).exists()).toBe(true);
      expect(findPlans()).toEqual(Object.values(plans));
    });

    describe('when data includes one invalid plan', () => {
      beforeEach(() => {
        const invalidPlanGroup = { bad_plan: invalidPlanWithName };
        mockPollingApi(200, invalidPlanGroup, {});
        return mountWrapper();
      });

      it('displays header text for one invalid plan', () => {
        expect(findHeader().text()).toBe('1 Terraform report failed to generate');
      });
    });

    describe('when data includes multiple invalid plans', () => {
      beforeEach(() => {
        const invalidPlanGroup = {
          bad_plan_one: invalidPlanWithName,
          bad_plan_two: invalidPlanWithName,
        };

        mockPollingApi(200, invalidPlanGroup, {});
        return mountWrapper();
      });

      it('displays header text for multiple invalid plans', () => {
        expect(findHeader().text()).toBe('2 Terraform reports failed to generate');
      });
    });

    describe('when data includes one valid plan', () => {
      beforeEach(() => {
        const validPlanGroup = { valid_plan: validPlanWithName };
        mockPollingApi(200, validPlanGroup, {});
        return mountWrapper();
      });

      it('displays header text for one valid plans', () => {
        expect(findHeader().text()).toBe('1 Terraform report was generated in your pipelines');
      });
    });

    describe('when data includes multiple valid plans', () => {
      beforeEach(() => {
        const validPlanGroup = {
          valid_plan_one: validPlanWithName,
          valid_plan_two: validPlanWithName,
        };
        mockPollingApi(200, validPlanGroup, {});
        return mountWrapper();
      });

      it('displays header text for multiple valid plans', () => {
        expect(findHeader().text()).toBe('2 Terraform reports were generated in your pipelines');
      });
    });
  });

  describe('polling', () => {
    let pollRequest;
    let pollStop;

    beforeEach(() => {
      pollRequest = jest.spyOn(Poll.prototype, 'makeRequest');
      pollStop = jest.spyOn(Poll.prototype, 'stop');
    });

    afterEach(() => {
      pollRequest.mockRestore();
      pollStop.mockRestore();
    });

    describe('successful poll', () => {
      beforeEach(() => {
        mockPollingApi(200, plans, {});

        return mountWrapper();
      });

      it('does not make additional requests after poll is successful', () => {
        expect(pollRequest).toHaveBeenCalledTimes(1);
        expect(pollStop).toHaveBeenCalledTimes(1);
      });
    });

    describe('polling fails', () => {
      beforeEach(() => {
        mockPollingApi(500, null, {});
        return mountWrapper();
      });

      it('stops loading', () => {
        expect(wrapper.findComponent(GlSkeletonLoader).exists()).toBe(false);
      });

      it('generates one broken plan', () => {
        expect(findPlans()).toEqual([{ tf_report_error: 'api_error' }]);
      });

      it('does not make additional requests after poll is unsuccessful', () => {
        expect(pollRequest).toHaveBeenCalledTimes(1);
        expect(pollStop).toHaveBeenCalledTimes(1);
      });
    });
  });
});