summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/actions_button_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/vue_shared/components/actions_button_spec.js')
-rw-r--r--spec/frontend/vue_shared/components/actions_button_spec.js203
1 files changed, 203 insertions, 0 deletions
diff --git a/spec/frontend/vue_shared/components/actions_button_spec.js b/spec/frontend/vue_shared/components/actions_button_spec.js
new file mode 100644
index 00000000000..4dde9d726d1
--- /dev/null
+++ b/spec/frontend/vue_shared/components/actions_button_spec.js
@@ -0,0 +1,203 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlDropdown, GlLink } from '@gitlab/ui';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import ActionsButton from '~/vue_shared/components/actions_button.vue';
+
+const TEST_ACTION = {
+ key: 'action1',
+ text: 'Sample',
+ secondaryText: 'Lorem ipsum.',
+ tooltip: '',
+ href: '/sample',
+ attrs: { 'data-test': '123' },
+};
+const TEST_ACTION_2 = {
+ key: 'action2',
+ text: 'Sample 2',
+ secondaryText: 'Dolar sit amit.',
+ tooltip: 'Dolar sit amit.',
+ href: '#',
+ attrs: { 'data-test': '456' },
+};
+const TEST_TOOLTIP = 'Lorem ipsum dolar sit';
+
+describe('Actions button component', () => {
+ let wrapper;
+
+ function createComponent(props) {
+ wrapper = shallowMount(ActionsButton, {
+ propsData: { ...props },
+ directives: { GlTooltip: createMockDirective() },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const getTooltip = child => {
+ const directiveBinding = getBinding(child.element, 'gl-tooltip');
+
+ return directiveBinding.value;
+ };
+ const findLink = () => wrapper.find(GlLink);
+ const findLinkTooltip = () => getTooltip(findLink());
+ const findDropdown = () => wrapper.find(GlDropdown);
+ const findDropdownTooltip = () => getTooltip(findDropdown());
+ const parseDropdownItems = () =>
+ findDropdown()
+ .findAll('gl-dropdown-item-stub,gl-dropdown-divider-stub')
+ .wrappers.map(x => {
+ if (x.is('gl-dropdown-divider-stub')) {
+ return { type: 'divider' };
+ }
+
+ const { isCheckItem, isChecked, secondaryText } = x.props();
+
+ return {
+ type: 'item',
+ isCheckItem,
+ isChecked,
+ secondaryText,
+ text: x.text(),
+ };
+ });
+ const clickOn = (child, evt = new Event('click')) => child.vm.$emit('click', evt);
+ const clickLink = (...args) => clickOn(findLink(), ...args);
+ const clickDropdown = (...args) => clickOn(findDropdown(), ...args);
+
+ describe('with 1 action', () => {
+ beforeEach(() => {
+ createComponent({ actions: [TEST_ACTION] });
+ });
+
+ it('should not render dropdown', () => {
+ expect(findDropdown().exists()).toBe(false);
+ });
+
+ it('should render single button', () => {
+ const link = findLink();
+
+ expect(link.attributes()).toEqual({
+ class: expect.any(String),
+ href: TEST_ACTION.href,
+ ...TEST_ACTION.attrs,
+ });
+ expect(link.text()).toBe(TEST_ACTION.text);
+ });
+
+ it('should have tooltip', () => {
+ expect(findLinkTooltip()).toBe(TEST_ACTION.tooltip);
+ });
+
+ it('should have attrs', () => {
+ expect(findLink().attributes()).toMatchObject(TEST_ACTION.attrs);
+ });
+
+ it('can click', () => {
+ expect(clickLink).not.toThrow();
+ });
+ });
+
+ describe('with 1 action with tooltip', () => {
+ it('should have tooltip', () => {
+ createComponent({ actions: [{ ...TEST_ACTION, tooltip: TEST_TOOLTIP }] });
+
+ expect(findLinkTooltip()).toBe(TEST_TOOLTIP);
+ });
+ });
+
+ describe('with 1 action with handle', () => {
+ it('can click and trigger handle', () => {
+ const handleClick = jest.fn();
+ createComponent({ actions: [{ ...TEST_ACTION, handle: handleClick }] });
+
+ const event = new Event('click');
+ clickLink(event);
+
+ expect(handleClick).toHaveBeenCalledWith(event);
+ });
+ });
+
+ describe('with multiple actions', () => {
+ let handleAction;
+
+ beforeEach(() => {
+ handleAction = jest.fn();
+
+ createComponent({ actions: [{ ...TEST_ACTION, handle: handleAction }, TEST_ACTION_2] });
+ });
+
+ it('should default to selecting first action', () => {
+ expect(findDropdown().attributes()).toMatchObject({
+ text: TEST_ACTION.text,
+ 'split-href': TEST_ACTION.href,
+ });
+ });
+
+ it('should handle first action click', () => {
+ const event = new Event('click');
+
+ clickDropdown(event);
+
+ expect(handleAction).toHaveBeenCalledWith(event);
+ });
+
+ it('should render dropdown items', () => {
+ expect(parseDropdownItems()).toEqual([
+ {
+ type: 'item',
+ isCheckItem: true,
+ isChecked: true,
+ secondaryText: TEST_ACTION.secondaryText,
+ text: TEST_ACTION.text,
+ },
+ { type: 'divider' },
+ {
+ type: 'item',
+ isCheckItem: true,
+ isChecked: false,
+ secondaryText: TEST_ACTION_2.secondaryText,
+ text: TEST_ACTION_2.text,
+ },
+ ]);
+ });
+
+ it('should select action 2 when clicked', () => {
+ expect(wrapper.emitted('select')).toBeUndefined();
+
+ const action2 = wrapper.find(`[data-testid="action_${TEST_ACTION_2.key}"]`);
+ action2.vm.$emit('click');
+
+ expect(wrapper.emitted('select')).toEqual([[TEST_ACTION_2.key]]);
+ });
+
+ it('should have tooltip value', () => {
+ expect(findDropdownTooltip()).toBe(TEST_ACTION.tooltip);
+ });
+ });
+
+ describe('with multiple actions and selectedKey', () => {
+ beforeEach(() => {
+ createComponent({ actions: [TEST_ACTION, TEST_ACTION_2], selectedKey: TEST_ACTION_2.key });
+ });
+
+ it('should show action 2 as selected', () => {
+ expect(parseDropdownItems()).toEqual([
+ expect.objectContaining({
+ type: 'item',
+ isChecked: false,
+ }),
+ { type: 'divider' },
+ expect.objectContaining({
+ type: 'item',
+ isChecked: true,
+ }),
+ ]);
+ });
+
+ it('should have tooltip value', () => {
+ expect(findDropdownTooltip()).toBe(TEST_ACTION_2.tooltip);
+ });
+ });
+});