summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/split_button_spec.js
blob: 6b869db40582e1d5e9f6d5eec2646c20914286c1 (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
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';

import { nextTick } from 'vue';
import SplitButton from '~/vue_shared/components/split_button.vue';

const mockActionItems = [
  {
    eventName: 'concert',
    title: 'professor',
    description: 'very symphonic',
  },
  {
    eventName: 'apocalypse',
    title: 'captain',
    description: 'warp drive',
  },
];

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

  const createComponent = (propsData) => {
    wrapper = shallowMount(SplitButton, {
      propsData,
    });
  };

  const findDropdown = () => wrapper.findComponent(GlDropdown);
  const findDropdownItem = (index = 0) =>
    findDropdown().findAllComponents(GlDropdownItem).at(index);
  const selectItem = async (index) => {
    findDropdownItem(index).vm.$emit('click');

    await nextTick();
  };
  const clickToggleButton = async () => {
    findDropdown().vm.$emit('click');

    await nextTick();
  };

  it('fails for empty actionItems', () => {
    const actionItems = [];
    expect(() => createComponent({ actionItems })).toThrow();
  });

  it('fails for single actionItems', () => {
    const actionItems = [mockActionItems[0]];
    expect(() => createComponent({ actionItems })).toThrow();
  });

  it('renders actionItems', () => {
    createComponent({ actionItems: mockActionItems });

    expect(wrapper.element).toMatchSnapshot();
  });

  describe('toggle button text', () => {
    beforeEach(() => {
      createComponent({ actionItems: mockActionItems });
    });

    it('defaults to first actionItems title', () => {
      expect(findDropdown().props().text).toBe(mockActionItems[0].title);
    });

    it('changes to selected actionItems title', () =>
      selectItem(1).then(() => {
        expect(findDropdown().props().text).toBe(mockActionItems[1].title);
      }));
  });

  describe('emitted event', () => {
    let eventHandler;
    let changeEventHandler;

    beforeEach(() => {
      createComponent({ actionItems: mockActionItems });
    });

    const addEventHandler = ({ eventName }) => {
      eventHandler = jest.fn();
      wrapper.vm.$once(eventName, () => eventHandler());
    };

    const addChangeEventHandler = () => {
      changeEventHandler = jest.fn();
      wrapper.vm.$once('change', (item) => changeEventHandler(item));
    };

    it('defaults to first actionItems event', () => {
      addEventHandler(mockActionItems[0]);

      return clickToggleButton().then(() => {
        expect(eventHandler).toHaveBeenCalled();
      });
    });

    it('changes to selected actionItems event', () =>
      selectItem(1)
        .then(() => addEventHandler(mockActionItems[1]))
        .then(clickToggleButton)
        .then(() => {
          expect(eventHandler).toHaveBeenCalled();
        }));

    it('change to selected actionItem emits change event', () => {
      addChangeEventHandler();

      return selectItem(1).then(() => {
        expect(changeEventHandler).toHaveBeenCalledWith(mockActionItems[1]);
      });
    });
  });
});