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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-02-11 03:17:04 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-11 03:17:04 +0300
commit18ad304adc191b31f11a311fc4b89e3ea8f0f328 (patch)
tree8a47b5a381887386705e3c3e4afc893c7eee2b37 /spec/frontend/listbox
parent9abffa14d6395d56b77313541d63e0c12ae2b602 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/listbox')
-rw-r--r--spec/frontend/listbox/index_spec.js111
-rw-r--r--spec/frontend/listbox/redirect_behavior_spec.js51
2 files changed, 162 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);
+ });
+ });
+});
diff --git a/spec/frontend/listbox/redirect_behavior_spec.js b/spec/frontend/listbox/redirect_behavior_spec.js
new file mode 100644
index 00000000000..7b2a40b65ce
--- /dev/null
+++ b/spec/frontend/listbox/redirect_behavior_spec.js
@@ -0,0 +1,51 @@
+import { initListbox } from '~/listbox';
+import { initRedirectListboxBehavior } from '~/listbox/redirect_behavior';
+import { redirectTo } from '~/lib/utils/url_utility';
+import { getFixture, setHTMLFixture } from 'helpers/fixtures';
+
+jest.mock('~/lib/utils/url_utility');
+jest.mock('~/listbox', () => ({
+ initListbox: jest.fn().mockReturnValue({ foo: true }),
+}));
+
+const fixture = getFixture('listbox/redirect_listbox.html');
+
+describe('initRedirectListboxBehavior', () => {
+ let instances;
+
+ beforeEach(() => {
+ setHTMLFixture(`
+ ${fixture}
+ ${fixture}
+ `);
+
+ instances = initRedirectListboxBehavior();
+ });
+
+ it('calls initListbox for each .js-redirect-listbox', () => {
+ expect(instances).toEqual([{ foo: true }, { foo: true }]);
+
+ expect(initListbox).toHaveBeenCalledTimes(2);
+
+ initListbox.mock.calls.forEach((callArgs, i) => {
+ const elements = document.querySelectorAll('.js-redirect-listbox');
+
+ expect(callArgs[0]).toBe(elements[i]);
+ expect(callArgs[1]).toEqual({
+ onChange: expect.any(Function),
+ });
+ });
+ });
+
+ it('passes onChange handler to initListbox that calls redirectTo', () => {
+ const [firstCallArgs] = initListbox.mock.calls;
+ const { onChange } = firstCallArgs[1];
+ const mockItem = { href: '/foo' };
+
+ expect(redirectTo).not.toHaveBeenCalled();
+
+ onChange(mockItem);
+
+ expect(redirectTo).toHaveBeenCalledWith(mockItem.href);
+ });
+});