2022-04-04 11:22:00 +05:30
|
|
|
import { nextTick } from 'vue';
|
2022-11-25 23:54:43 +05:30
|
|
|
import { getAllByRole, getByTestId } from '@testing-library/dom';
|
2023-03-04 22:38:38 +05:30
|
|
|
import { GlCollapsibleListbox } from '@gitlab/ui';
|
2022-04-04 11:22:00 +05:30
|
|
|
import { createWrapper } from '@vue/test-utils';
|
|
|
|
import { initListbox, parseAttributes } from '~/listbox';
|
2022-07-16 23:28:13 +05:30
|
|
|
import { getFixture, setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
|
2022-04-04 11:22:00 +05:30
|
|
|
|
|
|
|
jest.mock('~/lib/utils/url_utility');
|
|
|
|
|
|
|
|
const fixture = getFixture('listbox/redirect_listbox.html');
|
|
|
|
|
|
|
|
const parsedAttributes = (() => {
|
|
|
|
const div = document.createElement('div');
|
|
|
|
div.innerHTML = fixture;
|
|
|
|
return parseAttributes(div.firstChild);
|
|
|
|
})();
|
|
|
|
|
|
|
|
describe('initListbox', () => {
|
|
|
|
let instance;
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
if (instance) {
|
|
|
|
instance.$destroy();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const setup = (...args) => {
|
|
|
|
instance = initListbox(...args);
|
|
|
|
};
|
|
|
|
|
|
|
|
it('returns null given no element', () => {
|
|
|
|
setup();
|
|
|
|
|
|
|
|
expect(instance).toBe(null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('throws given an invalid element', () => {
|
|
|
|
expect(() => setup(document.body)).toThrow();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('given a valid element', () => {
|
|
|
|
let onChangeSpy;
|
|
|
|
|
2023-03-04 22:38:38 +05:30
|
|
|
const listbox = () => createWrapper(instance).findComponent(GlCollapsibleListbox);
|
2022-11-25 23:54:43 +05:30
|
|
|
const findToggleButton = () => getByTestId(document.body, 'base-dropdown-toggle');
|
|
|
|
const findSelectedItems = () => getAllByRole(document.body, 'option', { selected: true });
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
beforeEach(async () => {
|
|
|
|
setHTMLFixture(fixture);
|
|
|
|
onChangeSpy = jest.fn();
|
|
|
|
setup(document.querySelector('.js-redirect-listbox'), { onChange: onChangeSpy });
|
|
|
|
|
|
|
|
await nextTick();
|
|
|
|
});
|
|
|
|
|
2022-07-16 23:28:13 +05:30
|
|
|
afterEach(() => {
|
|
|
|
resetHTMLFixture();
|
|
|
|
});
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
it('returns an instance', () => {
|
|
|
|
expect(instance).not.toBe(null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders button with selected item text', () => {
|
|
|
|
expect(findToggleButton().textContent.trim()).toBe('Bar');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('has the correct item selected', () => {
|
|
|
|
const selectedItems = findSelectedItems();
|
|
|
|
expect(selectedItems).toHaveLength(1);
|
|
|
|
expect(selectedItems[0].textContent.trim()).toBe('Bar');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('applies additional classes from the original element', () => {
|
|
|
|
expect(instance.$el.classList).toContain('test-class-1', 'test-class-2');
|
|
|
|
});
|
|
|
|
|
2022-11-25 23:54:43 +05:30
|
|
|
describe.each(parsedAttributes.items)('selecting an item', (item) => {
|
2022-04-04 11:22:00 +05:30
|
|
|
beforeEach(async () => {
|
2022-11-25 23:54:43 +05:30
|
|
|
listbox().vm.$emit('select', item.value);
|
2022-04-04 11:22:00 +05:30
|
|
|
await nextTick();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('calls the onChange callback with the item', () => {
|
|
|
|
expect(onChangeSpy).toHaveBeenCalledWith(item);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('updates the toggle button text', () => {
|
|
|
|
expect(findToggleButton().textContent.trim()).toBe(item.text);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('marks the item as selected', () => {
|
|
|
|
const selectedItems = findSelectedItems();
|
|
|
|
expect(selectedItems).toHaveLength(1);
|
|
|
|
expect(selectedItems[0].textContent.trim()).toBe(item.text);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-04-23 21:23:45 +05:30
|
|
|
it('passes the "placement" prop through to the underlying component', () => {
|
|
|
|
expect(listbox().props('placement')).toBe(parsedAttributes.placement);
|
2022-04-04 11:22:00 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|