Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/listbox/index_spec.js')
-rw-r--r--spec/frontend/listbox/index_spec.js111
1 files changed, 111 insertions, 0 deletions
diff --git a/spec/frontend/listbox/index_spec.js b/spec/frontend/listbox/index_spec.js
new file mode 100644
index 00000000000..45659a0e523
--- /dev/null
+++ b/spec/frontend/listbox/index_spec.js
@@ -0,0 +1,111 @@
+import { nextTick } from 'vue';
+import { getAllByRole, getByRole } from '@testing-library/dom';
+import { GlDropdown } from '@gitlab/ui';
+import { createWrapper } from '@vue/test-utils';
+import { initListbox, parseAttributes } from '~/listbox';
+import { getFixture, setHTMLFixture } from 'helpers/fixtures';
+
+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);
+ };
+
+ // TODO: Rewrite these finders to use better semantics once the
+ // implementation is switched to GlListbox
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/348738
+ const findToggleButton = () => document.body.querySelector('.gl-dropdown-toggle');
+ const findItem = (text) => getByRole(document.body, 'menuitem', { name: text });
+ const findItems = () => getAllByRole(document.body, 'menuitem');
+ const findSelectedItems = () =>
+ findItems().filter(
+ (menuitem) =>
+ !menuitem
+ .querySelector('.gl-new-dropdown-item-check-icon')
+ .classList.contains('gl-visibility-hidden'),
+ );
+
+ 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;
+
+ beforeEach(async () => {
+ setHTMLFixture(fixture);
+ onChangeSpy = jest.fn();
+ setup(document.querySelector('.js-redirect-listbox'), { onChange: onChangeSpy });
+
+ await nextTick();
+ });
+
+ 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');
+ });
+
+ describe.each(parsedAttributes.items)('clicking on an item', (item) => {
+ beforeEach(async () => {
+ findItem(item.text).click();
+
+ 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);
+ });
+ });
+
+ it('passes the "right" prop through to the underlying component', () => {
+ const wrapper = createWrapper(instance).findComponent(GlDropdown);
+ expect(wrapper.props('right')).toBe(parsedAttributes.right);
+ });
+ });
+});