206 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| import { GlDropdown, GlDropdownDivider, GlButton } from '@gitlab/ui';
 | |
| import { shallowMount } from '@vue/test-utils';
 | |
| 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',
 | |
|     category: 'secondary',
 | |
|     href: '/sample',
 | |
|     variant: 'default',
 | |
|   },
 | |
| };
 | |
| 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 findButton = () => wrapper.find(GlButton);
 | |
|   const findButtonTooltip = () => getTooltip(findButton());
 | |
|   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(GlDropdownDivider)) {
 | |
|           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(findButton(), ...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', () => {
 | |
|       expect(findButton().attributes()).toMatchObject({
 | |
|         href: TEST_ACTION.href,
 | |
|         ...TEST_ACTION.attrs,
 | |
|       });
 | |
|       expect(findButton().text()).toBe(TEST_ACTION.text);
 | |
|     });
 | |
| 
 | |
|     it('should have tooltip', () => {
 | |
|       expect(findButtonTooltip()).toBe(TEST_ACTION.tooltip);
 | |
|     });
 | |
| 
 | |
|     it('should have attrs', () => {
 | |
|       expect(findButton().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(findButtonTooltip()).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);
 | |
|     });
 | |
|   });
 | |
| });
 |