summaryrefslogtreecommitdiff
path: root/spec/frontend/behaviors/copy_to_clipboard_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/behaviors/copy_to_clipboard_spec.js')
-rw-r--r--spec/frontend/behaviors/copy_to_clipboard_spec.js187
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);
+ });
+ });
+});