import initCopyToClipboard, { CLIPBOARD_SUCCESS_EVENT, CLIPBOARD_ERROR_EVENT, I18N_ERROR_MESSAGE, } from '~/behaviors/copy_to_clipboard'; import { show, hide, fixTitle, once } from '~/tooltips'; let onceCallback = () => {}; jest.mock('~/tooltips', () => ({ show: jest.fn(), hide: jest.fn(), fixTitle: jest.fn(), once: jest.fn((event, callback) => { onceCallback = callback; }), })); describe('initCopyToClipboard', () => { let clearSelection; let focusSpy; let dispatchEventSpy; let button; let clipboardInstance; afterEach(() => { document.body.innerHTML = ''; clipboardInstance = null; }); const title = 'Copy this value'; const defaultButtonAttributes = { 'data-clipboard-text': 'foo bar', title, 'data-title': title, }; const createButton = (attributes = {}) => { const combinedAttributes = { ...defaultButtonAttributes, ...attributes }; button = document.createElement('button'); Object.keys(combinedAttributes).forEach((attributeName) => { button.setAttribute(attributeName, combinedAttributes[attributeName]); }); document.body.appendChild(button); }; const init = () => { clipboardInstance = initCopyToClipboard(); }; const setupSpies = () => { clearSelection = jest.fn(); focusSpy = jest.spyOn(button, 'focus'); dispatchEventSpy = jest.spyOn(button, 'dispatchEvent'); }; const emitSuccessEvent = () => { clipboardInstance.emit('success', { action: 'copy', text: 'foo bar', trigger: button, clearSelection, }); }; const emitErrorEvent = () => { clipboardInstance.emit('error', { action: 'copy', text: 'foo bar', trigger: button, clearSelection, }); }; const itHandlesTooltip = (expectedTooltip) => { it('handles tooltip', () => { expect(button.getAttribute('title')).toBe(expectedTooltip); expect(button.getAttribute('aria-label')).toBe(expectedTooltip); expect(fixTitle).toHaveBeenCalledWith(button); expect(show).toHaveBeenCalledWith(button); expect(once).toHaveBeenCalledWith('hidden', expect.any(Function)); expect(hide).not.toHaveBeenCalled(); jest.runAllTimers(); expect(hide).toHaveBeenCalled(); onceCallback({ target: button }); expect(button.getAttribute('title')).toBe(title); expect(button.getAttribute('aria-label')).toBe(title); expect(fixTitle).toHaveBeenCalledWith(button); }); }; describe('when value is successfully copied', () => { it(`calls clearSelection, focuses the button, and dispatches ${CLIPBOARD_SUCCESS_EVENT} event`, () => { createButton(); init(); setupSpies(); emitSuccessEvent(); expect(clearSelection).toHaveBeenCalled(); expect(focusSpy).toHaveBeenCalled(); expect(dispatchEventSpy).toHaveBeenCalledWith(new Event(CLIPBOARD_SUCCESS_EVENT)); }); describe('when `data-clipboard-handle-tooltip` is set to `false`', () => { beforeEach(() => { createButton({ 'data-clipboard-handle-tooltip': 'false', }); init(); emitSuccessEvent(); }); it('does not handle success tooltip', () => { expect(show).not.toHaveBeenCalled(); }); }); describe('when `data-clipboard-handle-tooltip` is set to `true`', () => { beforeEach(() => { createButton({ 'data-clipboard-handle-tooltip': 'true', }); init(); emitSuccessEvent(); }); itHandlesTooltip('Copied'); }); describe('when `data-clipboard-handle-tooltip` is not set', () => { beforeEach(() => { createButton(); init(); emitSuccessEvent(); }); itHandlesTooltip('Copied'); }); }); describe('when there is an error copying the value', () => { it(`dispatches ${CLIPBOARD_ERROR_EVENT} event`, () => { createButton(); init(); setupSpies(); emitErrorEvent(); expect(dispatchEventSpy).toHaveBeenCalledWith(new Event(CLIPBOARD_ERROR_EVENT)); }); describe('when `data-clipboard-handle-tooltip` is set to `false`', () => { beforeEach(() => { createButton({ 'data-clipboard-handle-tooltip': 'false', }); init(); emitErrorEvent(); }); it('does not handle error tooltip', () => { expect(show).not.toHaveBeenCalled(); }); }); describe('when `data-clipboard-handle-tooltip` is set to `true`', () => { beforeEach(() => { createButton({ 'data-clipboard-handle-tooltip': 'true', }); init(); emitErrorEvent(); }); itHandlesTooltip(I18N_ERROR_MESSAGE); }); describe('when `data-clipboard-handle-tooltip` is not set', () => { beforeEach(() => { createButton(); init(); emitErrorEvent(); }); itHandlesTooltip(I18N_ERROR_MESSAGE); }); }); });