diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-20 13:43:29 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-20 13:43:29 +0300 |
commit | 3b1af5cc7ed2666ff18b718ce5d30fa5a2756674 (patch) | |
tree | 3bc4a40e0ee51ec27eabf917c537033c0c5b14d4 /spec/frontend/super_sidebar | |
parent | 9bba14be3f2c211bf79e15769cd9b77bc73a13bc (diff) |
Add latest changes from gitlab-org/gitlab@16-1-stable-eev16.1.0-rc42
Diffstat (limited to 'spec/frontend/super_sidebar')
17 files changed, 761 insertions, 248 deletions
diff --git a/spec/frontend/super_sidebar/components/brand_logo_spec.js b/spec/frontend/super_sidebar/components/brand_logo_spec.js new file mode 100644 index 00000000000..63c4bb9668b --- /dev/null +++ b/spec/frontend/super_sidebar/components/brand_logo_spec.js @@ -0,0 +1,42 @@ +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { createMockDirective } from 'helpers/vue_mock_directive'; +import BrandLogo from 'jh_else_ce/super_sidebar/components/brand_logo.vue'; + +describe('Brand Logo component', () => { + let wrapper; + + const defaultPropsData = { + logoUrl: 'path/to/logo', + }; + + const findBrandLogo = () => wrapper.findByTestId('brand-header-custom-logo'); + const findDefaultLogo = () => wrapper.findByTestId('brand-header-default-logo'); + + const createWrapper = (props = {}) => { + wrapper = shallowMountExtended(BrandLogo, { + provide: { + rootPath: '/', + }, + propsData: { + ...defaultPropsData, + ...props, + }, + directives: { + GlTooltip: createMockDirective('gl-tooltip'), + }, + }); + }; + + it('renders it', () => { + createWrapper(); + expect(findBrandLogo().exists()).toBe(true); + expect(findBrandLogo().attributes('src')).toBe(defaultPropsData.logoUrl); + }); + + it('when logoUrl given empty', () => { + createWrapper({ logoUrl: '' }); + + expect(findBrandLogo().exists()).toBe(false); + expect(findDefaultLogo().exists()).toBe(true); + }); +}); diff --git a/spec/frontend/super_sidebar/components/context_switcher_spec.js b/spec/frontend/super_sidebar/components/context_switcher_spec.js index 7928ee6400c..4317f451377 100644 --- a/spec/frontend/super_sidebar/components/context_switcher_spec.js +++ b/spec/frontend/super_sidebar/components/context_switcher_spec.js @@ -158,12 +158,6 @@ describe('ContextSwitcher component', () => { expect(findContextSwitcherToggle().props('expanded')).toEqual(false); }); - it("passes Popper.js' options to the disclosure dropdown", () => { - expect(findDisclosureDropdown().props('popperOptions')).toMatchObject({ - modifiers: expect.any(Array), - }); - }); - it('does not emit the `toggle` event initially', () => { expect(wrapper.emitted('toggle')).toBe(undefined); }); diff --git a/spec/frontend/super_sidebar/components/create_menu_spec.js b/spec/frontend/super_sidebar/components/create_menu_spec.js index 456085e23da..fe2fd17ae4d 100644 --- a/spec/frontend/super_sidebar/components/create_menu_spec.js +++ b/spec/frontend/super_sidebar/components/create_menu_spec.js @@ -6,7 +6,6 @@ import { GlDisclosureDropdownItem, } from '@gitlab/ui'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; -import { stubComponent } from 'helpers/stub_component'; import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue'; import { __ } from '~/locale'; import CreateMenu from '~/super_sidebar/components/create_menu.vue'; @@ -21,8 +20,6 @@ describe('CreateMenu component', () => { const findInviteMembersTrigger = () => wrapper.findComponent(InviteMembersTrigger); const findGlTooltip = () => wrapper.findComponent(GlTooltip); - const closeAndFocusMock = jest.fn(); - const createWrapper = () => { wrapper = shallowMountExtended(CreateMenu, { propsData: { @@ -30,9 +27,7 @@ describe('CreateMenu component', () => { }, stubs: { InviteMembersTrigger, - GlDisclosureDropdown: stubComponent(GlDisclosureDropdown, { - methods: { closeAndFocus: closeAndFocusMock }, - }), + GlDisclosureDropdown, }, }); }; @@ -42,11 +37,12 @@ describe('CreateMenu component', () => { createWrapper(); }); - it('passes popper options to the dropdown', () => { + it('passes custom offset to the dropdown', () => { createWrapper(); - expect(findGlDisclosureDropdown().props('popperOptions')).toEqual({ - modifiers: [{ name: 'offset', options: { offset: [-147, 4] } }], + expect(findGlDisclosureDropdown().props('dropdownOffset')).toEqual({ + crossAxis: -147, + mainAxis: 4, }); }); @@ -93,10 +89,5 @@ describe('CreateMenu component', () => { expect(findGlTooltip().exists()).toBe(true); }); - - it('closes the dropdown when invite members modal is opened', () => { - findInviteMembersTrigger().vm.$emit('modal-opened'); - expect(closeAndFocusMock).toHaveBeenCalled(); - }); }); }); diff --git a/spec/frontend/super_sidebar/components/frequent_items_list_spec.js b/spec/frontend/super_sidebar/components/frequent_items_list_spec.js index 5329a8f5da3..63dd941974a 100644 --- a/spec/frontend/super_sidebar/components/frequent_items_list_spec.js +++ b/spec/frontend/super_sidebar/components/frequent_items_list_spec.js @@ -1,4 +1,4 @@ -import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper'; import { s__ } from '~/locale'; import FrequentItemsList from '~/super_sidebar/components//frequent_items_list.vue'; import ItemsList from '~/super_sidebar/components/items_list.vue'; @@ -18,18 +18,20 @@ describe('FrequentItemsList component', () => { const findListTitle = () => wrapper.findByTestId('list-title'); const findItemsList = () => wrapper.findComponent(ItemsList); const findEmptyText = () => wrapper.findByTestId('empty-text'); + const findRemoveItemButton = () => wrapper.findByTestId('item-remove'); - const createWrapper = ({ props = {} } = {}) => { - wrapper = shallowMountExtended(FrequentItemsList, { + const createWrapperFactory = (mountFn = shallowMountExtended) => () => { + wrapper = mountFn(FrequentItemsList, { propsData: { title, pristineText, storageKey, maxItems, - ...props, }, }); }; + const createWrapper = createWrapperFactory(); + const createFullWrapper = createWrapperFactory(mountExtended); describe('default', () => { beforeEach(() => { @@ -64,16 +66,20 @@ describe('FrequentItemsList component', () => { it('does not render the empty text slot', () => { expect(findEmptyText().exists()).toBe(false); }); + }); - describe('items editing', () => { - it('remove-item event emission from items-list causes list item to be removed', async () => { - const localStorageProjects = findItemsList().props('items'); + describe('items editing', () => { + beforeEach(() => { + window.localStorage.setItem(storageKey, cachedFrequentProjects); + createFullWrapper(); + }); - await findItemsList().vm.$emit('remove-item', localStorageProjects[0]); + it('remove-item event emission from items-list causes list item to be removed', async () => { + const localStorageProjects = findItemsList().props('items'); + await findRemoveItemButton().trigger('click'); - expect(findItemsList().props('items')).toHaveLength(maxItems - 1); - expect(findItemsList().props('items')).not.toContain(localStorageProjects[0]); - }); + expect(findItemsList().props('items')).toHaveLength(maxItems - 1); + expect(findItemsList().props('items')).not.toContain(localStorageProjects[0]); }); }); }); diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/__snapshots__/search_item_spec.js.snap b/spec/frontend/super_sidebar/components/global_search/command_palette/__snapshots__/search_item_spec.js.snap new file mode 100644 index 00000000000..d16d137db2f --- /dev/null +++ b/spec/frontend/super_sidebar/components/global_search/command_palette/__snapshots__/search_item_spec.js.snap @@ -0,0 +1,122 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SearchItem should render the item 1`] = ` +<div + class="gl-display-flex gl-align-items-center" +> + <gl-avatar-stub + alt="avatar" + aria-hidden="true" + class="gl-mr-3" + entityid="37" + entityname="" + shape="rect" + size="16" + src="https://www.gravatar.com/avatar/a9638f4ec70148d51e56bf05ad41e993?s=80&d=identicon" + /> + + <!----> + + <span + class="gl-display-flex gl-flex-direction-column" + > + <span + class="gl-text-gray-900" + /> + + <!----> + </span> +</div> +`; + +exports[`SearchItem should render the item 2`] = ` +<div + class="gl-display-flex gl-align-items-center" +> + <!----> + + <gl-icon-stub + class="gl-mr-3" + name="users" + size="16" + /> + + <span + class="gl-display-flex gl-flex-direction-column" + > + <span + class="gl-text-gray-900" + > + Manage > Activity + </span> + + <!----> + </span> +</div> +`; + +exports[`SearchItem should render the item 3`] = ` +<div + class="gl-display-flex gl-align-items-center" +> + <gl-avatar-stub + alt="avatar" + aria-hidden="true" + class="gl-mr-3" + entityid="1" + entityname="MockProject1" + shape="rect" + size="32" + src="/project/avatar/1/avatar.png" + /> + + <!----> + + <span + class="gl-display-flex gl-flex-direction-column" + > + <span + class="gl-text-gray-900" + > + MockProject1 + </span> + + <span + class="gl-font-sm gl-text-gray-500" + > + Gitlab Org / MockProject1 + </span> + </span> +</div> +`; + +exports[`SearchItem should render the item 4`] = ` +<div + class="gl-display-flex gl-align-items-center" +> + <gl-avatar-stub + alt="avatar" + aria-hidden="true" + class="gl-mr-3" + entityid="7" + entityname="Flight" + shape="rect" + size="16" + src="" + /> + + <!----> + + <span + class="gl-display-flex gl-flex-direction-column" + > + <span + class="gl-text-gray-900" + > + Dismiss Cipher with no integrity + </span> + + <!----> + </span> +</div> +`; diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js b/spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js new file mode 100644 index 00000000000..21d085dc0fb --- /dev/null +++ b/spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js @@ -0,0 +1,143 @@ +import fuzzaldrinPlus from 'fuzzaldrin-plus'; +import { GlDisclosureDropdownGroup, GlDisclosureDropdownItem, GlLoadingIcon } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import MockAdapter from 'axios-mock-adapter'; +import CommandPaletteItems from '~/super_sidebar/components/global_search/command_palette/command_palette_items.vue'; +import { + COMMAND_HANDLE, + USERS_GROUP_TITLE, + USER_HANDLE, + SEARCH_SCOPE, +} from '~/super_sidebar/components/global_search/command_palette/constants'; +import { + commandMapper, + linksReducer, +} from '~/super_sidebar/components/global_search/command_palette/utils'; +import { getFormattedItem } from '~/super_sidebar/components/global_search/utils'; +import axios from '~/lib/utils/axios_utils'; +import { HTTP_STATUS_OK } from '~/lib/utils/http_status'; +import waitForPromises from 'helpers/wait_for_promises'; +import { COMMANDS, LINKS, USERS } from './mock_data'; + +const links = LINKS.reduce(linksReducer, []); + +describe('CommandPaletteItems', () => { + let wrapper; + const autocompletePath = '/autocomplete'; + const searchContext = { project: { id: 1 }, group: { id: 2 } }; + + const createComponent = (props) => { + wrapper = shallowMount(CommandPaletteItems, { + propsData: { + handle: COMMAND_HANDLE, + searchQuery: '', + ...props, + }, + stubs: { + GlDisclosureDropdownGroup, + GlDisclosureDropdownItem, + }, + provide: { + commandPaletteCommands: COMMANDS, + commandPaletteLinks: LINKS, + autocompletePath, + searchContext, + }, + }); + }; + + const findItems = () => wrapper.findAllComponents(GlDisclosureDropdownItem); + const findGroups = () => wrapper.findAllComponents(GlDisclosureDropdownGroup); + const findLoader = () => wrapper.findComponent(GlLoadingIcon); + + describe('COMMANDS & LINKS', () => { + it('renders all commands initially', () => { + createComponent(); + const commandGroup = COMMANDS.map(commandMapper)[0]; + expect(findItems()).toHaveLength(commandGroup.items.length); + expect(findGroups().at(0).props('group')).toEqual({ + name: commandGroup.name, + items: commandGroup.items, + }); + }); + + describe('with search query', () => { + it('should filter commands and links by the search query', async () => { + jest.spyOn(fuzzaldrinPlus, 'filter'); + createComponent({ searchQuery: 'mr' }); + const searchQuery = 'todo'; + await wrapper.setProps({ searchQuery }); + const commandGroup = COMMANDS.map(commandMapper)[0]; + expect(fuzzaldrinPlus.filter).toHaveBeenCalledWith( + commandGroup.items, + searchQuery, + expect.objectContaining({ key: 'text' }), + ); + expect(fuzzaldrinPlus.filter).toHaveBeenCalledWith( + links, + searchQuery, + expect.objectContaining({ key: 'keywords' }), + ); + }); + + it('should display no results message when no command matched the search query', async () => { + jest.spyOn(fuzzaldrinPlus, 'filter').mockReturnValue([]); + createComponent({ searchQuery: 'mr' }); + const searchQuery = 'todo'; + await wrapper.setProps({ searchQuery }); + expect(wrapper.text()).toBe('No results found'); + }); + }); + }); + + describe('USERS, ISSUES, PROJECTS', () => { + let mockAxios; + + beforeEach(() => { + mockAxios = new MockAdapter(axios); + }); + + it('should NOT start search by the search query which is less than 3 chars', () => { + jest.spyOn(axios, 'get'); + const searchQuery = 'us'; + createComponent({ handle: USER_HANDLE, searchQuery }); + + expect(axios.get).not.toHaveBeenCalled(); + + expect(findLoader().exists()).toBe(false); + }); + + it('should start scoped search with 3+ chars and display a loader', () => { + jest.spyOn(axios, 'get'); + const searchQuery = 'user'; + createComponent({ handle: USER_HANDLE, searchQuery }); + + expect(axios.get).toHaveBeenCalledWith( + `${autocompletePath}?term=${searchQuery}&project_id=${searchContext.project.id}&filter=search&scope=${SEARCH_SCOPE[USER_HANDLE]}`, + ); + expect(findLoader().exists()).toBe(true); + }); + + it('should render returned items', async () => { + mockAxios.onGet().replyOnce(HTTP_STATUS_OK, USERS); + + const searchQuery = 'user'; + createComponent({ handle: USER_HANDLE, searchQuery }); + + await waitForPromises(); + expect(findItems()).toHaveLength(USERS.length); + expect(findGroups().at(0).props('group')).toMatchObject({ + name: USERS_GROUP_TITLE, + items: USERS.map(getFormattedItem), + }); + }); + + it('should display no results message when no users matched the search query', async () => { + mockAxios.onGet().replyOnce(HTTP_STATUS_OK, []); + const searchQuery = 'user'; + createComponent({ handle: USER_HANDLE, searchQuery }); + await waitForPromises(); + expect(wrapper.text()).toBe('No results found'); + }); + }); +}); diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/fake_search_input_spec.js b/spec/frontend/super_sidebar/components/global_search/command_palette/fake_search_input_spec.js new file mode 100644 index 00000000000..a8e91395303 --- /dev/null +++ b/spec/frontend/super_sidebar/components/global_search/command_palette/fake_search_input_spec.js @@ -0,0 +1,44 @@ +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import FakeSearchInput from '~/super_sidebar/components/global_search/command_palette/fake_search_input.vue'; +import { + SEARCH_SCOPE_PLACEHOLDER, + COMMON_HANDLES, + COMMAND_HANDLE, +} from '~/super_sidebar/components/global_search/command_palette/constants'; + +describe('FakeSearchInput', () => { + let wrapper; + + const createComponent = (props) => { + wrapper = shallowMountExtended(FakeSearchInput, { + propsData: { + scope: COMMAND_HANDLE, + userInput: '', + ...props, + }, + }); + }; + + const findSearchScope = () => wrapper.findByTestId('search-scope'); + const findSearchScopePlaceholder = () => wrapper.findByTestId('search-scope-placeholder'); + + it('should render the search scope', () => { + createComponent(); + expect(findSearchScope().text()).toBe(COMMAND_HANDLE); + }); + + describe('placeholder', () => { + it.each(COMMON_HANDLES)( + 'should render the placeholder for the %s scope when there is no user input', + (scope) => { + createComponent({ scope }); + expect(findSearchScopePlaceholder().text()).toBe(SEARCH_SCOPE_PLACEHOLDER[scope]); + }, + ); + + it('should NOT render the placeholder when there is user input', () => { + createComponent({ userInput: 'todo' }); + expect(findSearchScopePlaceholder().exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js b/spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js new file mode 100644 index 00000000000..ec65a43d549 --- /dev/null +++ b/spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js @@ -0,0 +1,133 @@ +export const COMMANDS = [ + { + name: 'Global', + items: [ + { + text: 'New project/repository', + href: '/projects/new', + }, + { + text: 'New group', + href: '/groups/new', + }, + { + text: 'New snippet', + href: '/-/snippets/new', + }, + { + text: 'Invite members', + href: '/-/snippets/new', + component: 'invite_members', + }, + ], + }, +]; + +export const LINKS = [ + { + title: 'Manage', + icon: 'users', + link: '/flightjs/Flight/activity', + is_active: false, + pill_count: null, + items: [ + { + id: 'activity', + title: 'Activity', + icon: null, + link: '/flightjs/Flight/activity', + pill_count: null, + link_classes: 'shortcuts-project-activity', + is_active: false, + }, + { + id: 'members', + title: 'Members', + icon: null, + link: '/flightjs/Flight/-/project_members', + pill_count: null, + link_classes: null, + is_active: false, + }, + { + id: 'labels', + title: 'Labels', + icon: null, + link: '/flightjs/Flight/-/labels', + pill_count: null, + link_classes: null, + is_active: false, + }, + ], + separated: false, + }, +]; + +export const TRANSFORMED_LINKS = [ + { + href: '/flightjs/Flight/activity', + icon: 'users', + keywords: 'Manage', + text: 'Manage', + }, + { + href: '/flightjs/Flight/activity', + icon: 'users', + keywords: 'Activity', + text: 'Manage > Activity', + }, + { + href: '/flightjs/Flight/-/project_members', + icon: 'users', + keywords: 'Members', + text: 'Manage > Members', + }, + { + href: '/flightjs/Flight/-/labels', + icon: 'users', + keywords: 'Labels', + text: 'Manage > Labels', + }, +]; + +export const USERS = [ + { + id: 37, + username: 'reported_user_14', + name: 'Cole Dickinson', + web_url: 'http://127.0.0.1:3000/reported_user_14', + avatar_url: + 'https://www.gravatar.com/avatar/a9638f4ec70148d51e56bf05ad41e993?s=80\u0026d=identicon', + }, + { + id: 47, + username: 'sharlatenok', + name: 'Olena Horal-Koretska', + web_url: 'http://127.0.0.1:3000/sharlatenok', + }, + { + id: 30, + username: 'reported_user_7', + name: 'Violeta Feeney', + web_url: 'http://127.0.0.1:3000/reported_user_7', + }, +]; + +export const PROJECT = { + category: 'Projects', + id: 1, + label: 'Gitlab Org / MockProject1', + value: 'MockProject1', + url: 'project/1', + avatar_url: '/project/avatar/1/avatar.png', +}; + +export const ISSUE = { + avatar_url: '', + category: 'Recent issues', + id: 516, + label: 'Dismiss Cipher with no integrity', + project_id: 7, + project_name: 'Flight', + url: '/flightjs/Flight/-/issues/37', +}; diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/search_item_spec.js b/spec/frontend/super_sidebar/components/global_search/command_palette/search_item_spec.js new file mode 100644 index 00000000000..c7e49310588 --- /dev/null +++ b/spec/frontend/super_sidebar/components/global_search/command_palette/search_item_spec.js @@ -0,0 +1,33 @@ +import { shallowMount } from '@vue/test-utils'; +import SearchItem from '~/super_sidebar/components/global_search/command_palette/search_item.vue'; +import { getFormattedItem } from '~/super_sidebar/components/global_search/utils'; +import { linksReducer } from '~/super_sidebar/components/global_search/command_palette/utils'; +import { USERS, LINKS, PROJECT, ISSUE } from './mock_data'; + +jest.mock('~/lib/utils/highlight', () => ({ + __esModule: true, + default: (text) => text, +})); +const mockUser = getFormattedItem(USERS[0]); +const mockCommand = LINKS.reduce(linksReducer, [])[1]; +const mockProject = getFormattedItem(PROJECT); +const mockIssue = getFormattedItem(ISSUE); + +describe('SearchItem', () => { + let wrapper; + + const createComponent = (item) => { + wrapper = shallowMount(SearchItem, { + propsData: { + item, + searchQuery: 'root', + }, + }); + }; + + it.each([mockUser, mockCommand, mockProject, mockIssue])('should render the item', (item) => { + createComponent(item); + + expect(wrapper.element).toMatchSnapshot(); + }); +}); diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/utils_spec.js b/spec/frontend/super_sidebar/components/global_search/command_palette/utils_spec.js new file mode 100644 index 00000000000..0b75787723e --- /dev/null +++ b/spec/frontend/super_sidebar/components/global_search/command_palette/utils_spec.js @@ -0,0 +1,18 @@ +import { + commandMapper, + linksReducer, +} from '~/super_sidebar/components/global_search/command_palette/utils'; +import { COMMANDS, LINKS, TRANSFORMED_LINKS } from './mock_data'; + +describe('linksReducer', () => { + it('should transform links', () => { + expect(LINKS.reduce(linksReducer, [])).toEqual(TRANSFORMED_LINKS); + }); +}); + +describe('commandMapper', () => { + it('should temporarily remove the `invite_members` item', () => { + const initialCommandsLength = COMMANDS[0].items.length; + expect(COMMANDS.map(commandMapper)[0].items).toHaveLength(initialCommandsLength - 1); + }); +}); diff --git a/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js b/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js index f78e141afad..9b7b9e288df 100644 --- a/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js +++ b/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js @@ -7,6 +7,12 @@ import GlobalSearchModal from '~/super_sidebar/components/global_search/componen import GlobalSearchAutocompleteItems from '~/super_sidebar/components/global_search/components/global_search_autocomplete_items.vue'; import GlobalSearchDefaultItems from '~/super_sidebar/components/global_search/components/global_search_default_items.vue'; import GlobalSearchScopedItems from '~/super_sidebar/components/global_search/components/global_search_scoped_items.vue'; +import FakeSearchInput from '~/super_sidebar/components/global_search/command_palette/fake_search_input.vue'; +import CommandPaletteItems from '~/super_sidebar/components/global_search/command_palette/command_palette_items.vue'; +import { + SEARCH_OR_COMMAND_MODE_PLACEHOLDER, + COMMON_HANDLES, +} from '~/super_sidebar/components/global_search/command_palette/constants'; import { SEARCH_INPUT_DESCRIPTION, SEARCH_RESULTS_DESCRIPTION, @@ -17,6 +23,7 @@ import { IS_SEARCHING, SEARCH_SHORTCUTS_MIN_CHARACTERS, } from '~/super_sidebar/components/global_search/constants'; +import { SEARCH_GITLAB } from '~/vue_shared/global_search/constants'; import { truncate } from '~/lib/utils/text_utility'; import { visitUrl } from '~/lib/utils/url_utility'; import { ENTER_KEY } from '~/lib/utils/keys'; @@ -53,7 +60,18 @@ describe('GlobalSearchModal', () => { }, }; - const createComponent = (initialState, mockGetters, stubs) => { + const defaultMockGetters = { + searchQuery: () => MOCK_SEARCH_QUERY, + searchOptions: () => MOCK_DEFAULT_SEARCH_OPTIONS, + scopedSearchOptions: () => MOCK_SCOPED_SEARCH_OPTIONS, + }; + + const createComponent = ( + initialState = deafaultMockState, + mockGetters = defaultMockGetters, + stubs, + glFeatures = { commandPalette: false }, + ) => { const store = new Vuex.Store({ state: { ...deafaultMockState, @@ -71,6 +89,7 @@ describe('GlobalSearchModal', () => { wrapper = shallowMountExtended(GlobalSearchModal, { store, stubs, + provide: { glFeatures }, }); }; @@ -98,6 +117,8 @@ describe('GlobalSearchModal', () => { wrapper.findComponent(GlobalSearchAutocompleteItems); const findSearchInputDescription = () => wrapper.find(`#${SEARCH_INPUT_DESCRIPTION}`); const findSearchResultsDescription = () => wrapper.findByTestId(SEARCH_RESULTS_DESCRIPTION); + const findCommandPaletteItems = () => wrapper.findComponent(CommandPaletteItems); + const findFakeSearchInput = () => wrapper.findComponent(FakeSearchInput); describe('template', () => { describe('always renders', () => { @@ -281,6 +302,45 @@ describe('GlobalSearchModal', () => { ).toBe(iconName); }); }); + + describe('Command palette', () => { + describe('when FF `command_palette` is disabled', () => { + beforeEach(() => { + createComponent(); + }); + + it('should not render command mode components', () => { + expect(findCommandPaletteItems().exists()).toBe(false); + expect(findFakeSearchInput().exists()).toBe(false); + }); + + it('should provide default placeholder to the search input', () => { + expect(findGlobalSearchInput().attributes('placeholder')).toBe(SEARCH_GITLAB); + }); + }); + + describe.each(COMMON_HANDLES)( + 'when FF `command_palette` is enabled and search handle is %s', + (handle) => { + beforeEach(() => { + createComponent({ search: handle }, undefined, undefined, { + commandPalette: true, + }); + }); + + it('should render command mode components', () => { + expect(findCommandPaletteItems().exists()).toBe(true); + expect(findFakeSearchInput().exists()).toBe(true); + }); + + it('should provide an alternative placeholder to the search input', () => { + expect(findGlobalSearchInput().attributes('placeholder')).toBe( + SEARCH_OR_COMMAND_MODE_PLACEHOLDER, + ); + }); + }, + ); + }); }); describe('events', () => { diff --git a/spec/frontend/super_sidebar/components/help_center_spec.js b/spec/frontend/super_sidebar/components/help_center_spec.js index 808c30436a3..6af1172e4d8 100644 --- a/spec/frontend/super_sidebar/components/help_center_spec.js +++ b/spec/frontend/super_sidebar/components/help_center_spec.js @@ -4,7 +4,7 @@ import toggleWhatsNewDrawer from '~/whats_new'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import HelpCenter from '~/super_sidebar/components/help_center.vue'; import { helpPagePath } from '~/helpers/help_page_helper'; -import { DOMAIN, PROMO_URL } from 'jh_else_ce/lib/utils/url_utility'; +import { DOCS_URL, FORUM_URL, PROMO_URL } from 'jh_else_ce/lib/utils/url_utility'; import { useLocalStorageSpy } from 'helpers/local_storage_helper'; import { STORAGE_KEY } from '~/whats_new/utils/notification'; import { helpCenterState } from '~/super_sidebar/constants'; @@ -25,6 +25,7 @@ describe('HelpCenter component', () => { }; const withinComponent = () => within(wrapper.element); const findButton = (name) => withinComponent().getByRole('button', { name }); + const findNotificationDot = () => wrapper.findByTestId('notification-dot'); // eslint-disable-next-line no-shadow const createWrapper = (sidebarData) => { @@ -52,7 +53,7 @@ describe('HelpCenter component', () => { }, { text: HelpCenter.i18n.docs, - href: `https://docs.${DOMAIN}`, + href: DOCS_URL, extraAttrs: trackingAttrs('gitlab_documentation'), }, { @@ -62,7 +63,7 @@ describe('HelpCenter component', () => { }, { text: HelpCenter.i18n.forum, - href: `https://forum.${DOMAIN}/`, + href: FORUM_URL, extraAttrs: trackingAttrs('community_forum'), }, { @@ -91,22 +92,22 @@ describe('HelpCenter component', () => { ]); }); - it('passes popper options to the dropdown', () => { - expect(findDropdown().props('popperOptions')).toEqual({ - modifiers: [{ name: 'offset', options: { offset: [-4, 4] } }], + it('passes custom offset to the dropdown', () => { + expect(findDropdown().props('dropdownOffset')).toEqual({ + crossAxis: -4, + mainAxis: 4, }); }); describe('with show_tanuki_bot true', () => { beforeEach(() => { createWrapper({ ...sidebarData, show_tanuki_bot: true }); - jest.spyOn(wrapper.vm.$refs.dropdown, 'close'); }); it('shows Ask GitLab Chat with the help items', () => { expect(findDropdownGroup(0).props('group').items).toEqual([ expect.objectContaining({ - icon: 'tanuki', + icon: 'tanuki-ai', text: HelpCenter.i18n.chat, extraAttrs: trackingAttrs('tanuki_bot_help_dropdown'), }), @@ -119,10 +120,6 @@ describe('HelpCenter component', () => { findButton('Ask GitLab Chat').click(); }); - it('closes the dropdown', () => { - expect(wrapper.vm.$refs.dropdown.close).toHaveBeenCalled(); - }); - it('sets helpCenterState.showTanukiBotChatDrawer to true', () => { expect(helpCenterState.showTanukiBotChatDrawer).toBe(true); }); @@ -150,16 +147,9 @@ describe('HelpCenter component', () => { let button; beforeEach(() => { - jest.spyOn(wrapper.vm.$refs.dropdown, 'close'); - button = findButton('Keyboard shortcuts ?'); }); - it('closes the dropdown', () => { - button.click(); - expect(wrapper.vm.$refs.dropdown.close).toHaveBeenCalled(); - }); - it('shows the keyboard shortcuts modal', () => { // This relies on the event delegation set up by the Shortcuts class in // ~/behaviors/shortcuts/shortcuts.js. @@ -179,17 +169,12 @@ describe('HelpCenter component', () => { describe('showWhatsNew', () => { beforeEach(() => { - jest.spyOn(wrapper.vm.$refs.dropdown, 'close'); beforeEach(() => { createWrapper({ ...sidebarData, show_version_check: true }); }); findButton("What's new 5").click(); }); - it('closes the dropdown', () => { - expect(wrapper.vm.$refs.dropdown.close).toHaveBeenCalled(); - }); - it('shows the "What\'s new" slideout', () => { expect(toggleWhatsNewDrawer).toHaveBeenCalledWith(expect.any(Object)); }); @@ -219,8 +204,8 @@ describe('HelpCenter component', () => { createWrapper({ ...sidebarData, display_whats_new: false }); }); - it('is false', () => { - expect(wrapper.vm.showWhatsNewNotification).toBe(false); + it('does not render notification dot', () => { + expect(findNotificationDot().exists()).toBe(false); }); }); @@ -231,8 +216,8 @@ describe('HelpCenter component', () => { createWrapper({ ...sidebarData, display_whats_new: true }); }); - it('is true', () => { - expect(wrapper.vm.showWhatsNewNotification).toBe(true); + it('renders notification dot', () => { + expect(findNotificationDot().exists()).toBe(true); }); describe('when "What\'s new" drawer got opened', () => { @@ -240,8 +225,8 @@ describe('HelpCenter component', () => { findButton("What's new 5").click(); }); - it('is false', () => { - expect(wrapper.vm.showWhatsNewNotification).toBe(false); + it('does not render notification dot', () => { + expect(findNotificationDot().exists()).toBe(false); }); }); @@ -251,8 +236,8 @@ describe('HelpCenter component', () => { createWrapper({ ...sidebarData, display_whats_new: true }); }); - it('is false', () => { - expect(wrapper.vm.showWhatsNewNotification).toBe(false); + it('does not render notification dot', () => { + expect(findNotificationDot().exists()).toBe(false); }); }); }); diff --git a/spec/frontend/super_sidebar/components/items_list_spec.js b/spec/frontend/super_sidebar/components/items_list_spec.js index d5e8043cce9..8e00984f500 100644 --- a/spec/frontend/super_sidebar/components/items_list_spec.js +++ b/spec/frontend/super_sidebar/components/items_list_spec.js @@ -1,5 +1,4 @@ -import { GlIcon } from '@gitlab/ui'; -import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import ItemsList from '~/super_sidebar/components/items_list.vue'; import NavItem from '~/super_sidebar/components/nav_item.vue'; import { cachedFrequentProjects } from '../mock_data'; @@ -12,8 +11,8 @@ describe('ItemsList component', () => { const findNavItems = () => wrapper.findAllComponents(NavItem); - const createWrapper = ({ props = {}, slots = {}, mountFn = shallowMountExtended } = {}) => { - wrapper = mountFn(ItemsList, { + const createWrapper = ({ props = {}, slots = {} } = {}) => { + wrapper = shallowMountExtended(ItemsList, { propsData: { ...props, }, @@ -61,41 +60,4 @@ describe('ItemsList component', () => { expect(wrapper.findByTestId(testId).exists()).toBe(true); }); - - describe('item removal', () => { - const findRemoveButton = () => wrapper.findByTestId('item-remove'); - const mockProject = { - ...firstMockedProject, - title: firstMockedProject.name, - }; - - beforeEach(() => { - createWrapper({ - props: { - items: [mockProject], - }, - mountFn: mountExtended, - }); - }); - - it('renders the remove button', () => { - const itemRemoveButton = findRemoveButton(); - - expect(itemRemoveButton.exists()).toBe(true); - expect(itemRemoveButton.attributes('title')).toBe('Remove'); - expect(itemRemoveButton.findComponent(GlIcon).props('name')).toBe('dash'); - }); - - it('emits `remove-item` event with item param when remove button is clicked', () => { - const itemRemoveButton = findRemoveButton(); - - itemRemoveButton.vm.$emit( - 'click', - { stopPropagation: jest.fn(), preventDefault: jest.fn() }, - mockProject, - ); - - expect(wrapper.emitted('remove-item')).toEqual([[mockProject]]); - }); - }); }); diff --git a/spec/frontend/super_sidebar/components/sidebar_menu_spec.js b/spec/frontend/super_sidebar/components/sidebar_menu_spec.js index 9b726b620dd..21e5220edd9 100644 --- a/spec/frontend/super_sidebar/components/sidebar_menu_spec.js +++ b/spec/frontend/super_sidebar/components/sidebar_menu_spec.js @@ -1,6 +1,8 @@ -import { mountExtended } from 'helpers/vue_test_utils_helper'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import SidebarMenu from '~/super_sidebar/components/sidebar_menu.vue'; import PinnedSection from '~/super_sidebar/components/pinned_section.vue'; +import NavItem from '~/super_sidebar/components/nav_item.vue'; +import MenuSection from '~/super_sidebar/components/menu_section.vue'; import { PANELS_WITH_PINS } from '~/super_sidebar/constants'; import { sidebarData } from '../mock_data'; @@ -11,174 +13,142 @@ const menuItems = [ { id: 4, title: 'Also with subitems', items: [{ id: 41, title: 'Subitem' }] }, ]; -describe('SidebarMenu component', () => { +describe('Sidebar Menu', () => { let wrapper; - const createWrapper = (mockData) => { - wrapper = mountExtended(SidebarMenu, { + const createWrapper = (extraProps = {}) => { + wrapper = shallowMountExtended(SidebarMenu, { propsData: { - items: mockData.current_menu_items, - pinnedItemIds: mockData.pinned_items, - panelType: mockData.panel_type, - updatePinsUrl: mockData.update_pins_url, + items: sidebarData.current_menu_items, + pinnedItemIds: sidebarData.pinned_items, + panelType: sidebarData.panel_type, + updatePinsUrl: sidebarData.update_pins_url, + ...extraProps, }, }); }; + const findStaticItemsSection = () => wrapper.findByTestId('static-items-section'); + const findStaticItems = () => findStaticItemsSection().findAllComponents(NavItem); const findPinnedSection = () => wrapper.findComponent(PinnedSection); const findMainMenuSeparator = () => wrapper.findByTestId('main-menu-separator'); - - describe('computed', () => { - describe('supportsPins', () => { - it('is true for the project sidebar', () => { - createWrapper({ ...sidebarData, panel_type: 'project' }); - expect(wrapper.vm.supportsPins).toBe(true); - }); - - it('is true for the group sidebar', () => { - createWrapper({ ...sidebarData, panel_type: 'group' }); - expect(wrapper.vm.supportsPins).toBe(true); - }); - - it('is false for any other sidebar', () => { - createWrapper({ ...sidebarData, panel_type: 'your_work' }); - expect(wrapper.vm.supportsPins).toEqual(false); + const findNonStaticItemsSection = () => wrapper.findByTestId('non-static-items-section'); + const findNonStaticItems = () => findNonStaticItemsSection().findAllComponents(NavItem); + const findNonStaticSectionItems = () => + findNonStaticItemsSection().findAllComponents(MenuSection); + + describe('Static section', () => { + describe('when the sidebar supports pins', () => { + beforeEach(() => { + createWrapper({ + items: menuItems, + panelType: PANELS_WITH_PINS[0], + }); }); - }); - describe('flatPinnableItems', () => { - it('returns all subitems in a flat array', () => { - createWrapper({ ...sidebarData, current_menu_items: menuItems }); - expect(wrapper.vm.flatPinnableItems).toEqual([ - { id: 21, title: 'Pinned subitem' }, - { id: 41, title: 'Subitem' }, + it('renders static items section', () => { + expect(findStaticItemsSection().exists()).toBe(true); + expect(findStaticItems().wrappers.map((w) => w.props('item').title)).toEqual([ + 'No subitems', + 'Empty subitems array', ]); }); }); - describe('staticItems', () => { - describe('when the sidebar supports pins', () => { - beforeEach(() => { - createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - panel_type: PANELS_WITH_PINS[0], - }); + describe('when the sidebar does not support pins', () => { + beforeEach(() => { + createWrapper({ + items: menuItems, + panelType: 'explore', }); + }); - it('makes everything that has no subitems a static item', () => { - expect(wrapper.vm.staticItems.map((i) => i.title)).toEqual([ - 'No subitems', - 'Empty subitems array', - ]); - }); + it('does not render static items section', () => { + expect(findStaticItemsSection().exists()).toBe(false); }); + }); + }); - describe('when the sidebar does not support pins', () => { - beforeEach(() => { - createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - panel_type: 'explore', - }); - }); + describe('Pinned section', () => { + it('is rendered in a project sidebar', () => { + createWrapper({ panelType: 'project' }); + expect(findPinnedSection().exists()).toBe(true); + }); - it('returns an empty array', () => { - expect(wrapper.vm.staticItems.map((i) => i.title)).toEqual([]); - }); - }); + it('is rendered in a group sidebar', () => { + createWrapper({ panelType: 'group' }); + expect(findPinnedSection().exists()).toBe(true); }); - describe('nonStaticItems', () => { - describe('when the sidebar supports pins', () => { - beforeEach(() => { - createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - panel_type: PANELS_WITH_PINS[0], - }); - }); + it('is not rendered in other sidebars', () => { + createWrapper({ panelType: 'your_work' }); + expect(findPinnedSection().exists()).toBe(false); + }); + }); - it('keeps items that have subitems (aka "sections") as non-static', () => { - expect(wrapper.vm.nonStaticItems.map((i) => i.title)).toEqual([ - 'With subitems', - 'Also with subitems', - ]); + describe('Non static items section', () => { + describe('when the sidebar supports pins', () => { + beforeEach(() => { + createWrapper({ + items: menuItems, + panelType: PANELS_WITH_PINS[0], }); }); - describe('when the sidebar does not support pins', () => { - beforeEach(() => { - createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - panel_type: 'explore', - }); - }); - - it('keeps all items as non-static', () => { - expect(wrapper.vm.nonStaticItems).toEqual(menuItems); - }); + it('keeps items that have subitems (aka "sections") as non-static', () => { + expect(findNonStaticSectionItems().wrappers.map((w) => w.props('item').title)).toEqual([ + 'With subitems', + 'Also with subitems', + ]); }); }); - describe('pinnedItems', () => { - describe('when user has no pinned item ids stored', () => { - beforeEach(() => { - createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - pinned_items: [], - }); - }); - - it('returns an empty array', () => { - expect(wrapper.vm.pinnedItems).toEqual([]); + describe('when the sidebar does not support pins', () => { + beforeEach(() => { + createWrapper({ + items: menuItems, + panelType: 'explore', }); }); - describe('when user has some pinned item ids stored', () => { - beforeEach(() => { - createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - pinned_items: [21], - }); - }); - - it('returns the items matching the pinned ids', () => { - expect(wrapper.vm.pinnedItems).toEqual([{ id: 21, title: 'Pinned subitem' }]); - }); + it('keeps all items as non-static', () => { + expect(findNonStaticSectionItems().length + findNonStaticItems().length).toBe( + menuItems.length, + ); }); }); }); - describe('Menu separators', () => { + describe('Separators', () => { it('should add the separator above pinned section', () => { createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - panel_type: 'project', + items: menuItems, + panelType: 'project', }); expect(findPinnedSection().props('separated')).toBe(true); }); it('should add the separator above main menu items when there is a pinned section', () => { createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - panel_type: PANELS_WITH_PINS[0], + items: menuItems, + panelType: PANELS_WITH_PINS[0], }); expect(findMainMenuSeparator().exists()).toBe(true); }); it('should NOT add the separator above main menu items when there is no pinned section', () => { createWrapper({ - ...sidebarData, - current_menu_items: menuItems, - panel_type: 'explore', + items: menuItems, + panelType: 'explore', }); expect(findMainMenuSeparator().exists()).toBe(false); }); }); + + describe('ARIA attributes', () => { + it('adds aria-label attribute to nav element', () => { + createWrapper(); + expect(wrapper.find('nav').attributes('aria-label')).toBe('Main navigation'); + }); + }); }); diff --git a/spec/frontend/super_sidebar/components/user_bar_spec.js b/spec/frontend/super_sidebar/components/user_bar_spec.js index 6878e724c65..ae48c0f2a75 100644 --- a/spec/frontend/super_sidebar/components/user_bar_spec.js +++ b/spec/frontend/super_sidebar/components/user_bar_spec.js @@ -5,6 +5,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { __ } from '~/locale'; import CreateMenu from '~/super_sidebar/components/create_menu.vue'; import SearchModal from '~/super_sidebar/components/global_search/components/global_search.vue'; +import BrandLogo from 'jh_else_ce/super_sidebar/components/brand_logo.vue'; import MergeRequestMenu from '~/super_sidebar/components/merge_request_menu.vue'; import Counter from '~/super_sidebar/components/counter.vue'; import UserBar from '~/super_sidebar/components/user_bar.vue'; @@ -23,7 +24,7 @@ describe('UserBar component', () => { const findMRsCounter = () => findCounter(1); const findTodosCounter = () => findCounter(2); const findMergeRequestMenu = () => wrapper.findComponent(MergeRequestMenu); - const findBrandLogo = () => wrapper.findByTestId('brand-header-custom-logo'); + const findBrandLogo = () => wrapper.findComponent(BrandLogo); const findCollapseButton = () => wrapper.findByTestId('super-sidebar-collapse-button'); const findSearchButton = () => wrapper.findByTestId('super-sidebar-search-button'); const findSearchModal = () => wrapper.findComponent(SearchModal); @@ -47,7 +48,6 @@ describe('UserBar component', () => { sidebarData: { ...sidebarData, ...extraSidebarData }, }, provide: { - rootPath: '/', toggleNewNavEndpoint: '/-/profile/preferences', isImpersonating: false, ...provideOverrides, @@ -116,7 +116,7 @@ describe('UserBar component', () => { it('renders branding logo', () => { expect(findBrandLogo().exists()).toBe(true); - expect(findBrandLogo().attributes('src')).toBe(sidebarData.logo_url); + expect(findBrandLogo().props('logoUrl')).toBe(sidebarData.logo_url); }); it('does not render the "Stop impersonating" button', () => { diff --git a/spec/frontend/super_sidebar/components/user_menu_spec.js b/spec/frontend/super_sidebar/components/user_menu_spec.js index cf8f650ec8f..f0f18ca9185 100644 --- a/spec/frontend/super_sidebar/components/user_menu_spec.js +++ b/spec/frontend/super_sidebar/components/user_menu_spec.js @@ -1,5 +1,6 @@ import { GlAvatar, GlDisclosureDropdown } from '@gitlab/ui'; import { mountExtended } from 'helpers/vue_test_utils_helper'; +import { stubComponent } from 'helpers/stub_component'; import UserMenu from '~/super_sidebar/components/user_menu.vue'; import UserNameGroup from '~/super_sidebar/components/user_name_group.vue'; import NewNavToggle from '~/nav/components/new_nav_toggle.vue'; @@ -17,7 +18,9 @@ describe('UserMenu component', () => { const findDropdown = () => wrapper.findComponent(GlDisclosureDropdown); const showDropdown = () => findDropdown().vm.$emit('shown'); - const createWrapper = (userDataChanges = {}) => { + const closeDropdownSpy = jest.fn(); + + const createWrapper = (userDataChanges = {}, stubs = {}) => { wrapper = mountExtended(UserMenu, { propsData: { data: { @@ -28,6 +31,7 @@ describe('UserMenu component', () => { stubs: { GlEmoji, GlAvatar: true, + ...stubs, }, provide: { toggleNewNavEndpoint, @@ -37,11 +41,12 @@ describe('UserMenu component', () => { trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); }; - it('passes popper options to the dropdown', () => { + it('passes custom offset to the dropdown', () => { createWrapper(); - expect(findDropdown().props('popperOptions')).toEqual({ - modifiers: [{ name: 'offset', options: { offset: [-211, 4] } }], + expect(findDropdown().props('dropdownOffset')).toEqual({ + crossAxis: -211, + mainAxis: 4, }); }); @@ -79,8 +84,8 @@ describe('UserMenu component', () => { describe('User status item', () => { let item; - const setItem = ({ can_update, busy, customized } = {}) => { - createWrapper({ status: { ...userMenuMockStatus, can_update, busy, customized } }); + const setItem = ({ can_update, busy, customized, stubs } = {}) => { + createWrapper({ status: { ...userMenuMockStatus, can_update, busy, customized } }, stubs); item = wrapper.findByTestId('status-item'); }; @@ -103,11 +108,19 @@ describe('UserMenu component', () => { }); it('should close the dropdown when status modal opened', () => { - setItem({ can_update: true }); - wrapper.vm.$refs.userDropdown.close = jest.fn(); - expect(wrapper.vm.$refs.userDropdown.close).not.toHaveBeenCalled(); + setItem({ + can_update: true, + stubs: { + GlDisclosureDropdown: stubComponent(GlDisclosureDropdown, { + methods: { + close: closeDropdownSpy, + }, + }), + }, + }); + expect(closeDropdownSpy).not.toHaveBeenCalled(); item.vm.$emit('action'); - expect(wrapper.vm.$refs.userDropdown.close).toHaveBeenCalled(); + expect(closeDropdownSpy).toHaveBeenCalled(); }); describe('renders correct label', () => { diff --git a/spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js b/spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js index 909f4249e28..771d1f07fea 100644 --- a/spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js +++ b/spec/frontend/super_sidebar/super_sidebar_collapsed_state_manager_spec.js @@ -42,22 +42,19 @@ describe('Super Sidebar Collapsed State Manager', () => { describe('toggleSuperSidebarCollapsed', () => { it.each` - collapsed | saveCookie | windowWidth | hasClass | superSidebarPeek | isPeekable - ${true} | ${true} | ${xl} | ${true} | ${false} | ${false} - ${true} | ${true} | ${xl} | ${true} | ${true} | ${true} - ${true} | ${false} | ${xl} | ${true} | ${false} | ${false} - ${true} | ${true} | ${sm} | ${true} | ${false} | ${false} - ${true} | ${false} | ${sm} | ${true} | ${false} | ${false} - ${false} | ${true} | ${xl} | ${false} | ${false} | ${false} - ${false} | ${true} | ${xl} | ${false} | ${true} | ${false} - ${false} | ${false} | ${xl} | ${false} | ${false} | ${false} - ${false} | ${true} | ${sm} | ${false} | ${false} | ${false} - ${false} | ${false} | ${sm} | ${false} | ${false} | ${false} + collapsed | saveCookie | windowWidth | hasClass | isPeekable + ${true} | ${true} | ${xl} | ${true} | ${true} + ${true} | ${false} | ${xl} | ${true} | ${true} + ${true} | ${true} | ${sm} | ${true} | ${true} + ${true} | ${false} | ${sm} | ${true} | ${true} + ${false} | ${true} | ${xl} | ${false} | ${false} + ${false} | ${false} | ${xl} | ${false} | ${false} + ${false} | ${true} | ${sm} | ${false} | ${false} + ${false} | ${false} | ${sm} | ${false} | ${false} `( 'when collapsed is $collapsed, saveCookie is $saveCookie, and windowWidth is $windowWidth then page class contains `page-with-super-sidebar-collapsed` is $hasClass', - ({ collapsed, saveCookie, windowWidth, hasClass, superSidebarPeek, isPeekable }) => { + ({ collapsed, saveCookie, windowWidth, hasClass, isPeekable }) => { jest.spyOn(bp, 'windowWidth').mockReturnValue(windowWidth); - gon.features = { superSidebarPeek }; toggleSuperSidebarCollapsed(collapsed, saveCookie); |