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

key_spec.js « components « deploy_keys « frontend « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 5410914da040a20fd41d1f395db66188f7cbe323 (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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import VueApollo from 'vue-apollo';
import Vue, { nextTick } from 'vue';
import { mount } from '@vue/test-utils';
import enabledKeys from 'test_fixtures/deploy_keys/enabled_keys.json';
import availablePublicKeys from 'test_fixtures/deploy_keys/available_public_keys.json';
import { createAlert } from '~/alert';
import { mapDeployKey } from '~/deploy_keys/graphql/resolvers';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import key from '~/deploy_keys/components/key.vue';
import ActionBtn from '~/deploy_keys/components/action_btn.vue';
import { getTimeago, localeDateFormat } from '~/lib/utils/datetime_utility';

jest.mock('~/alert');

Vue.use(VueApollo);

describe('Deploy keys key', () => {
  let wrapper;
  let currentScopeMock;

  const findTextAndTrim = (selector) => wrapper.find(selector).text().trim();

  const createComponent = async (propsData) => {
    const resolvers = {
      Query: {
        currentScope: currentScopeMock,
      },
    };

    const apolloProvider = createMockApollo([], resolvers);
    wrapper = mount(key, {
      propsData: {
        endpoint: 'https://test.host/dummy/endpoint',
        ...propsData,
      },
      apolloProvider,
      directives: {
        GlTooltip: createMockDirective('gl-tooltip'),
      },
    });
    await nextTick();
  };

  beforeEach(() => {
    currentScopeMock = jest.fn();
  });

  describe('enabled key', () => {
    const deployKey = mapDeployKey(enabledKeys.keys[0]);

    beforeEach(() => {
      currentScopeMock.mockReturnValue('enabledKeys');
    });

    it('renders the keys title', async () => {
      await createComponent({ deployKey });

      expect(findTextAndTrim('.title')).toContain('My title');
    });

    it('renders human friendly formatted created date', async () => {
      await createComponent({ deployKey });

      expect(findTextAndTrim('.key-created-at')).toBe(
        `${getTimeago().format(deployKey.createdAt)}`,
      );
    });

    it('renders human friendly expiration date', async () => {
      const expiresAt = new Date();
      await createComponent({
        deployKey: { ...deployKey, expiresAt },
      });

      expect(findTextAndTrim('.key-expires-at')).toBe(`${getTimeago().format(expiresAt)}`);
    });
    it('shows tooltip for expiration date', async () => {
      const expiresAt = new Date();
      await createComponent({
        deployKey: { ...deployKey, expiresAt },
      });

      const expiryComponent = wrapper.find('[data-testid="expires-at-tooltip"]');
      const tooltip = getBinding(expiryComponent.element, 'gl-tooltip');
      expect(tooltip).toBeDefined();
      expect(expiryComponent.attributes('title')).toBe(
        `${localeDateFormat.asDateTimeFull.format(expiresAt)}`,
      );
    });
    it('renders never when no expiration date', async () => {
      await createComponent({
        deployKey: { ...deployKey, expiresAt: null },
      });

      expect(wrapper.find('[data-testid="expires-never"]').exists()).toBe(true);
    });

    it('shows pencil button for editing', async () => {
      await createComponent({ deployKey });

      expect(wrapper.find('.btn [data-testid="pencil-icon"]').exists()).toBe(true);
    });

    it('shows disable button when the project is not deletable', async () => {
      await createComponent({ deployKey });
      await waitForPromises();

      expect(wrapper.find('.btn [data-testid="cancel-icon"]').exists()).toBe(true);
    });

    it('shows remove button when the project is deletable', async () => {
      await createComponent({
        deployKey: { ...deployKey, destroyedWhenOrphaned: true, almostOrphaned: true },
      });
      await waitForPromises();
      expect(wrapper.find('.btn [data-testid="remove-icon"]').exists()).toBe(true);
    });
  });

  describe('deploy key labels', () => {
    const deployKey = mapDeployKey(enabledKeys.keys[0]);
    const deployKeysProjects = [...deployKey.deployKeysProjects];
    it('shows write access title when key has write access', async () => {
      deployKeysProjects[0] = { ...deployKeysProjects[0], canPush: true };
      await createComponent({ deployKey: { ...deployKey, deployKeysProjects } });

      expect(wrapper.find('.deploy-project-label').attributes('title')).toBe(
        'Grant write permissions to this key',
      );
    });

    it('does not show write access title when key has write access', async () => {
      deployKeysProjects[0] = { ...deployKeysProjects[0], canPush: false };
      await createComponent({ deployKey: { ...deployKey, deployKeysProjects } });

      expect(wrapper.find('.deploy-project-label').attributes('title')).toBe('Read access only');
    });

    it('shows expandable button if more than two projects', async () => {
      await createComponent({ deployKey });
      const labels = wrapper.findAll('.deploy-project-label');

      expect(labels.length).toBe(2);
      expect(labels.at(1).text()).toContain('others');
      expect(labels.at(1).attributes('title')).toContain('Expand');
    });

    it('expands all project labels after click', async () => {
      await createComponent({ deployKey });
      const { length } = deployKey.deployKeysProjects;
      wrapper.findAll('.deploy-project-label').at(1).trigger('click');

      await nextTick();
      const labels = wrapper.findAll('.deploy-project-label');

      expect(labels).toHaveLength(length);
      expect(labels.at(1).text()).not.toContain(`+${length} others`);
      expect(labels.at(1).attributes('title')).not.toContain('Expand');
    });

    it('shows two projects', async () => {
      await createComponent({
        deployKey: { ...deployKey, deployKeysProjects: [...deployKeysProjects].slice(0, 2) },
      });

      const labels = wrapper.findAll('.deploy-project-label');

      expect(labels.length).toBe(2);
      expect(labels.at(1).text()).toContain(deployKey.deployKeysProjects[1].project.fullName);
    });
  });

  describe('public keys', () => {
    const deployKey = mapDeployKey(availablePublicKeys.keys[0]);

    it('renders deploy keys without any enabled projects', async () => {
      await createComponent({ deployKey: { ...deployKey, deployKeysProjects: [] } });

      expect(findTextAndTrim('.deploy-project-list')).toBe('None');
    });

    it('shows enable button', async () => {
      await createComponent({ deployKey });
      expect(findTextAndTrim('.btn')).toBe('Enable');
    });

    it('shows an error on enable failure', async () => {
      await createComponent({ deployKey });

      const error = new Error('oops!');
      wrapper.findComponent(ActionBtn).vm.$emit('error', error);

      await nextTick();

      expect(createAlert).toHaveBeenCalledWith({
        message: 'Error enabling deploy key',
        captureError: true,
        error,
      });
    });

    it('shows pencil button for editing', async () => {
      await createComponent({ deployKey });
      expect(wrapper.find('.btn [data-testid="pencil-icon"]').exists()).toBe(true);
    });

    it('shows disable button when key is enabled', async () => {
      currentScopeMock.mockReturnValue('enabledKeys');
      await createComponent({ deployKey });
      await waitForPromises();

      expect(wrapper.find('.btn [data-testid="cancel-icon"]').exists()).toBe(true);
    });
  });
});