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

labels_select_root_spec.js « labels_select_widget « sidebar « components « vue_shared « frontend « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: d4203528874fd8136cb9948ed866a65377bb0a7e (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
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import { IssuableType } from '~/issue_show/constants';
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue';
import DropdownValue from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue';
import issueLabelsQuery from '~/vue_shared/components/sidebar/labels_select_widget/graphql/issue_labels.query.graphql';
import LabelsSelectRoot from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue';
import { mockConfig, issuableLabelsQueryResponse } from './mock_data';

jest.mock('~/flash');

const localVue = createLocalVue();
localVue.use(VueApollo);

const successfulQueryHandler = jest.fn().mockResolvedValue(issuableLabelsQueryResponse);
const errorQueryHandler = jest.fn().mockRejectedValue('Houston, we have a problem');

describe('LabelsSelectRoot', () => {
  let wrapper;

  const findSidebarEditableItem = () => wrapper.findComponent(SidebarEditableItem);
  const findDropdownValue = () => wrapper.findComponent(DropdownValue);
  const findDropdownContents = () => wrapper.findComponent(DropdownContents);

  const createComponent = ({
    config = mockConfig,
    slots = {},
    queryHandler = successfulQueryHandler,
  } = {}) => {
    const mockApollo = createMockApollo([[issueLabelsQuery, queryHandler]]);

    wrapper = shallowMount(LabelsSelectRoot, {
      slots,
      apolloProvider: mockApollo,
      localVue,
      propsData: {
        ...config,
        issuableType: IssuableType.Issue,
        labelCreateType: 'project',
        workspaceType: 'project',
      },
      stubs: {
        SidebarEditableItem,
      },
      provide: {
        canUpdate: true,
        allowLabelEdit: true,
        allowLabelCreate: true,
        labelsManagePath: 'test',
      },
    });
  };

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

  it('renders component with classes `labels-select-wrapper position-relative`', () => {
    createComponent();
    expect(wrapper.classes()).toEqual(['labels-select-wrapper', 'position-relative']);
  });

  it.each`
    variant         | cssClass
    ${'standalone'} | ${'is-standalone'}
    ${'embedded'}   | ${'is-embedded'}
  `(
    'renders component root element with CSS class `$cssClass` when `state.variant` is "$variant"',
    async ({ variant, cssClass }) => {
      createComponent({
        config: { ...mockConfig, variant },
      });

      await nextTick();
      expect(wrapper.classes()).toContain(cssClass);
    },
  );

  describe('if dropdown variant is `sidebar`', () => {
    it('renders sidebar editable item', () => {
      createComponent();
      expect(findSidebarEditableItem().exists()).toBe(true);
    });

    it('passes true `loading` prop to sidebar editable item when loading labels', () => {
      createComponent();
      expect(findSidebarEditableItem().props('loading')).toBe(true);
    });

    describe('when labels are fetched successfully', () => {
      beforeEach(async () => {
        createComponent();
        await waitForPromises();
      });

      it('passes true `loading` prop to sidebar editable item', () => {
        expect(findSidebarEditableItem().props('loading')).toBe(false);
      });

      it('renders dropdown value component when query labels is resolved', () => {
        expect(findDropdownValue().exists()).toBe(true);
        expect(findDropdownValue().props('selectedLabels')).toEqual(
          issuableLabelsQueryResponse.data.workspace.issuable.labels.nodes,
        );
      });

      it('emits `onLabelRemove` event on dropdown value label remove event', () => {
        const label = { id: 'gid://gitlab/ProjectLabel/1' };
        findDropdownValue().vm.$emit('onLabelRemove', label);
        expect(wrapper.emitted('onLabelRemove')).toEqual([[label]]);
      });
    });

    it('creates flash with error message when query is rejected', async () => {
      createComponent({ queryHandler: errorQueryHandler });
      await waitForPromises();
      expect(createFlash).toHaveBeenCalledWith({ message: 'Error fetching labels.' });
    });
  });

  it('emits `updateSelectedLabels` event on dropdown contents `setLabels` event if iid is not set', async () => {
    const label = { id: 'gid://gitlab/ProjectLabel/1' };
    createComponent({ config: { ...mockConfig, iid: undefined } });

    findDropdownContents().vm.$emit('setLabels', [label]);
    expect(wrapper.emitted('updateSelectedLabels')).toEqual([[{ labels: [label] }]]);
  });
});