2021-12-02 00:17:32 +00:00
|
|
|
import { merge } from 'lodash';
|
|
|
|
import { GlFormInputGroup } from '@gitlab/ui';
|
|
|
|
|
|
|
|
import InputCopyToggleVisibility from '~/vue_shared/components/form/input_copy_toggle_visibility.vue';
|
|
|
|
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
|
|
|
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
|
|
|
|
|
|
|
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
|
|
|
|
|
|
|
describe('InputCopyToggleVisibility', () => {
|
|
|
|
let wrapper;
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
wrapper.destroy();
|
|
|
|
});
|
|
|
|
|
|
|
|
const valueProp = 'hR8x1fuJbzwu5uFKLf9e';
|
|
|
|
|
|
|
|
const createComponent = (options = {}) => {
|
|
|
|
wrapper = mountExtended(
|
|
|
|
InputCopyToggleVisibility,
|
|
|
|
merge({}, options, {
|
|
|
|
directives: {
|
|
|
|
GlTooltip: createMockDirective(),
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const findFormInputGroup = () => wrapper.findComponent(GlFormInputGroup);
|
|
|
|
const findFormInput = () => findFormInputGroup().find('input');
|
|
|
|
const findRevealButton = () =>
|
|
|
|
wrapper.findByRole('button', {
|
|
|
|
name: InputCopyToggleVisibility.i18n.toggleVisibilityLabelReveal,
|
|
|
|
});
|
|
|
|
const findHideButton = () =>
|
|
|
|
wrapper.findByRole('button', {
|
|
|
|
name: InputCopyToggleVisibility.i18n.toggleVisibilityLabelHide,
|
|
|
|
});
|
|
|
|
const findCopyButton = () => wrapper.findComponent(ClipboardButton);
|
|
|
|
const createCopyEvent = () => {
|
|
|
|
const event = new Event('copy', { cancelable: true });
|
|
|
|
Object.assign(event, { preventDefault: jest.fn(), clipboardData: { setData: jest.fn() } });
|
|
|
|
|
|
|
|
return event;
|
|
|
|
};
|
|
|
|
|
|
|
|
const itDoesNotModifyCopyEvent = () => {
|
|
|
|
it('does not modify copy event', () => {
|
|
|
|
const event = createCopyEvent();
|
|
|
|
|
|
|
|
findFormInput().element.dispatchEvent(event);
|
|
|
|
|
|
|
|
expect(event.clipboardData.setData).not.toHaveBeenCalled();
|
|
|
|
expect(event.preventDefault).not.toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
describe('when `value` prop is passed', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({
|
|
|
|
propsData: {
|
|
|
|
value: valueProp,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('displays value as hidden', () => {
|
2022-06-07 15:08:12 +00:00
|
|
|
expect(findFormInput().element.value).toBe('********************');
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('saves actual value to clipboard when manually copied', () => {
|
|
|
|
const event = createCopyEvent();
|
|
|
|
findFormInput().element.dispatchEvent(event);
|
|
|
|
|
|
|
|
expect(event.clipboardData.setData).toHaveBeenCalledWith('text/plain', valueProp);
|
|
|
|
expect(event.preventDefault).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
|
2022-06-03 15:09:26 +00:00
|
|
|
it('emits `copy` event when manually copied the token', () => {
|
|
|
|
expect(wrapper.emitted('copy')).toBeUndefined();
|
|
|
|
|
|
|
|
findFormInput().element.dispatchEvent(createCopyEvent());
|
|
|
|
|
2022-06-07 12:08:05 +00:00
|
|
|
expect(wrapper.emitted()).toHaveProperty('copy');
|
2022-06-03 15:09:26 +00:00
|
|
|
expect(wrapper.emitted('copy')).toHaveLength(1);
|
|
|
|
expect(wrapper.emitted('copy')[0]).toEqual([]);
|
|
|
|
});
|
|
|
|
|
2021-12-02 00:17:32 +00:00
|
|
|
describe('visibility toggle button', () => {
|
|
|
|
it('renders a reveal button', () => {
|
|
|
|
const revealButton = findRevealButton();
|
|
|
|
|
|
|
|
expect(revealButton.exists()).toBe(true);
|
|
|
|
|
|
|
|
const tooltip = getBinding(revealButton.element, 'gl-tooltip');
|
|
|
|
|
|
|
|
expect(tooltip.value).toBe(InputCopyToggleVisibility.i18n.toggleVisibilityLabelReveal);
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when clicked', () => {
|
2022-04-14 03:08:57 +00:00
|
|
|
let event;
|
|
|
|
|
2021-12-02 00:17:32 +00:00
|
|
|
beforeEach(async () => {
|
2022-04-14 03:08:57 +00:00
|
|
|
event = { stopPropagation: jest.fn() };
|
|
|
|
await findRevealButton().trigger('click', event);
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('displays value', () => {
|
2022-06-07 15:08:12 +00:00
|
|
|
expect(findFormInput().element.value).toBe(valueProp);
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('renders a hide button', () => {
|
|
|
|
const hideButton = findHideButton();
|
|
|
|
|
|
|
|
expect(hideButton.exists()).toBe(true);
|
|
|
|
|
|
|
|
const tooltip = getBinding(hideButton.element, 'gl-tooltip');
|
|
|
|
|
|
|
|
expect(tooltip.value).toBe(InputCopyToggleVisibility.i18n.toggleVisibilityLabelHide);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('emits `visibility-change` event', () => {
|
|
|
|
expect(wrapper.emitted('visibility-change')[0]).toEqual([true]);
|
|
|
|
});
|
2022-04-14 03:08:57 +00:00
|
|
|
|
|
|
|
it('stops propagation on click event', () => {
|
|
|
|
// in case the input is located in a dropdown or modal
|
|
|
|
expect(event.stopPropagation).toHaveBeenCalledTimes(1);
|
|
|
|
});
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('copy button', () => {
|
|
|
|
it('renders button with correct props passed', () => {
|
|
|
|
expect(findCopyButton().props()).toMatchObject({
|
|
|
|
text: valueProp,
|
|
|
|
title: 'Copy',
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when clicked', () => {
|
|
|
|
beforeEach(async () => {
|
|
|
|
await findCopyButton().trigger('click');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('emits `copy` event', () => {
|
2022-06-07 12:08:05 +00:00
|
|
|
expect(wrapper.emitted()).toHaveProperty('copy');
|
|
|
|
expect(wrapper.emitted('copy')).toHaveLength(1);
|
2021-12-02 00:17:32 +00:00
|
|
|
expect(wrapper.emitted('copy')[0]).toEqual([]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when `value` prop is not passed', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('displays value as hidden with 20 asterisks', () => {
|
2022-06-07 15:08:12 +00:00
|
|
|
expect(findFormInput().element.value).toBe('********************');
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when `initialVisibility` prop is `true`', () => {
|
2022-06-07 15:08:12 +00:00
|
|
|
const label = 'My label';
|
|
|
|
|
2021-12-02 00:17:32 +00:00
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({
|
|
|
|
propsData: {
|
|
|
|
value: valueProp,
|
|
|
|
initialVisibility: true,
|
2022-06-07 15:08:12 +00:00
|
|
|
label,
|
|
|
|
'label-for': 'my-input',
|
|
|
|
formInputGroupProps: {
|
|
|
|
id: 'my-input',
|
|
|
|
},
|
2021-12-02 00:17:32 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('displays value', () => {
|
2022-06-07 15:08:12 +00:00
|
|
|
expect(findFormInput().element.value).toBe(valueProp);
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
itDoesNotModifyCopyEvent();
|
2022-06-07 15:08:12 +00:00
|
|
|
|
|
|
|
describe('when input is clicked', () => {
|
|
|
|
it('selects input value', async () => {
|
|
|
|
const mockSelect = jest.fn();
|
|
|
|
wrapper.vm.$refs.input.$el.select = mockSelect;
|
|
|
|
await wrapper.findByLabelText(label).trigger('click');
|
|
|
|
|
|
|
|
expect(mockSelect).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when label is clicked', () => {
|
|
|
|
it('selects input value', async () => {
|
|
|
|
const mockSelect = jest.fn();
|
|
|
|
wrapper.vm.$refs.input.$el.select = mockSelect;
|
|
|
|
await wrapper.find('label').trigger('click');
|
|
|
|
|
|
|
|
expect(mockSelect).toHaveBeenCalled();
|
|
|
|
});
|
|
|
|
});
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('when `showToggleVisibilityButton` is `false`', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({
|
|
|
|
propsData: {
|
|
|
|
value: valueProp,
|
|
|
|
showToggleVisibilityButton: false,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not render visibility toggle button', () => {
|
|
|
|
expect(findRevealButton().exists()).toBe(false);
|
|
|
|
expect(findHideButton().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('displays value', () => {
|
2022-06-07 15:08:12 +00:00
|
|
|
expect(findFormInput().element.value).toBe(valueProp);
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
itDoesNotModifyCopyEvent();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('when `showCopyButton` is `false`', () => {
|
|
|
|
beforeEach(() => {
|
|
|
|
createComponent({
|
|
|
|
propsData: {
|
|
|
|
showCopyButton: false,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('does not render copy button', () => {
|
|
|
|
expect(findCopyButton().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2022-06-07 15:08:12 +00:00
|
|
|
it('passes `formInputGroupProps` prop only to the input', () => {
|
2021-12-02 00:17:32 +00:00
|
|
|
createComponent({
|
|
|
|
propsData: {
|
|
|
|
formInputGroupProps: {
|
2022-06-07 15:08:12 +00:00
|
|
|
name: 'Foo bar',
|
|
|
|
'data-qa-selector': 'Foo bar',
|
|
|
|
class: 'Foo bar',
|
|
|
|
id: 'Foo bar',
|
2021-12-02 00:17:32 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2022-06-07 15:08:12 +00:00
|
|
|
expect(findFormInput().attributes()).toMatchObject({
|
|
|
|
name: 'Foo bar',
|
|
|
|
'data-qa-selector': 'Foo bar',
|
|
|
|
class: expect.stringContaining('Foo bar'),
|
|
|
|
id: 'Foo bar',
|
|
|
|
});
|
|
|
|
|
|
|
|
const attributesInputGroup = findFormInputGroup().attributes();
|
|
|
|
expect(attributesInputGroup.name).toBeUndefined();
|
|
|
|
expect(attributesInputGroup['data-qa-selector']).toBeUndefined();
|
|
|
|
expect(attributesInputGroup.class).not.toContain('Foo bar');
|
|
|
|
expect(attributesInputGroup.id).toBeUndefined();
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('passes `copyButtonTitle` prop to `ClipboardButton`', () => {
|
|
|
|
createComponent({
|
|
|
|
propsData: {
|
|
|
|
copyButtonTitle: 'Copy token',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(findCopyButton().props('title')).toBe('Copy token');
|
|
|
|
});
|
2021-12-10 21:11:20 +00:00
|
|
|
|
|
|
|
it('renders slots in `gl-form-group`', () => {
|
|
|
|
const description = 'Mock input description';
|
|
|
|
createComponent({
|
|
|
|
slots: {
|
|
|
|
description,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(wrapper.findByText(description).exists()).toBe(true);
|
|
|
|
});
|
2021-12-02 00:17:32 +00:00
|
|
|
});
|