188 lines
4.9 KiB
JavaScript
188 lines
4.9 KiB
JavaScript
|
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);
|
||
|
});
|
||
|
});
|
||
|
});
|