diff options
Diffstat (limited to 'spec/frontend/behaviors/copy_to_clipboard_spec.js')
-rw-r--r-- | spec/frontend/behaviors/copy_to_clipboard_spec.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/spec/frontend/behaviors/copy_to_clipboard_spec.js b/spec/frontend/behaviors/copy_to_clipboard_spec.js new file mode 100644 index 00000000000..c5beaa0ba5d --- /dev/null +++ b/spec/frontend/behaviors/copy_to_clipboard_spec.js @@ -0,0 +1,187 @@ +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); + }); + }); +}); |