summaryrefslogtreecommitdiff
path: root/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js
blob: 35a9c30095344675464918adb2fabf7ba6625f69 (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
import Vue from 'vue';
import $ from 'jquery';

import dropdownValueComponent from '~/vue_shared/components/sidebar/labels_select/dropdown_value.vue';

import mountComponent from 'spec/helpers/vue_mount_component_helper';

import { mockConfig, mockLabels } from './mock_data';

const createComponent = (
  labels = mockLabels,
  labelFilterBasePath = mockConfig.labelFilterBasePath,
) => {
  const Component = Vue.extend(dropdownValueComponent);

  return mountComponent(Component, {
    labels,
    labelFilterBasePath,
    enableScopedLabels: true,
  });
};

describe('DropdownValueComponent', () => {
  let vm;

  beforeEach(() => {
    vm = createComponent();
  });

  afterEach(() => {
    vm.$destroy();
  });

  describe('computed', () => {
    describe('isEmpty', () => {
      it('returns true if `labels` prop is empty', () => {
        const vmEmptyLabels = createComponent([]);

        expect(vmEmptyLabels.isEmpty).toBe(true);
        vmEmptyLabels.$destroy();
      });

      it('returns false if `labels` prop is empty', () => {
        expect(vm.isEmpty).toBe(false);
      });
    });
  });

  describe('methods', () => {
    describe('labelFilterUrl', () => {
      it('returns URL string starting with labelFilterBasePath and encoded label.title', () => {
        expect(
          vm.labelFilterUrl({
            title: 'Foo bar',
          }),
        ).toBe('/gitlab-org/my-project/issues?label_name[]=Foo%20bar');
      });
    });

    describe('labelStyle', () => {
      it('returns object with `color` & `backgroundColor` properties from label.textColor & label.color', () => {
        const label = {
          textColor: '#FFFFFF',
          color: '#BADA55',
        };
        const styleObj = vm.labelStyle(label);

        expect(styleObj.color).toBe(label.textColor);
        expect(styleObj.backgroundColor).toBe(label.color);
      });
    });

    describe('scopedLabelsDescription', () => {
      it('returns html for tooltip', () => {
        const html = vm.scopedLabelsDescription(mockLabels[1]);
        const $el = $.parseHTML(html);

        expect($el[0]).toHaveClass('scoped-label-tooltip-title');
        expect($el[2].textContent).toEqual(mockLabels[1].description);
      });
    });

    describe('showScopedLabels', () => {
      it('returns true if the label is scoped label', () => {
        expect(vm.showScopedLabels(mockLabels[1])).toBe(true);
      });

      it('returns false when label is a regular label', () => {
        expect(vm.showScopedLabels(mockLabels[0])).toBe(false);
      });
    });
  });

  describe('template', () => {
    it('renders component container element with classes `hide-collapsed value issuable-show-labels`', () => {
      expect(vm.$el.classList.contains('hide-collapsed', 'value', 'issuable-show-labels')).toBe(
        true,
      );
    });

    it('render slot content inside component when `labels` prop is empty', () => {
      const vmEmptyLabels = createComponent([]);

      expect(vmEmptyLabels.$el.querySelector('.text-secondary').innerText.trim()).toBe(
        mockConfig.emptyValueText,
      );
      vmEmptyLabels.$destroy();
    });

    it('renders label element with filter URL', () => {
      expect(vm.$el.querySelector('a').getAttribute('href')).toBe(
        '/gitlab-org/my-project/issues?label_name[]=Foo%20Label',
      );
    });

    it('renders label element and styles based on label details', () => {
      const labelEl = vm.$el.querySelector('a span.badge.color-label');

      expect(labelEl).not.toBeNull();
      expect(labelEl.getAttribute('style')).toBe('background-color: rgb(186, 218, 85);');
      expect(labelEl.innerText.trim()).toBe(mockLabels[0].title);
    });

    describe('label is of scoped-label type', () => {
      it('renders a scoped-label-wrapper span to incorporate 2 anchors', () => {
        expect(vm.$el.querySelector('span.scoped-label-wrapper')).not.toBeNull();
      });

      it('renders anchor tag containing question icon', () => {
        const anchor = vm.$el.querySelector('.scoped-label-wrapper a.scoped-label');

        expect(anchor).not.toBeNull();
        expect(anchor.querySelector('i.fa-question-circle')).not.toBeNull();
      });
    });
  });
});