diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-18 11:18:50 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-18 11:18:50 +0000 |
commit | 8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch) | |
tree | a77e7fe7a93de11213032ed4ab1f33a3db51b738 /spec/frontend/global_search_input_spec.js | |
parent | 00b35af3db1abfe813a778f643dad221aad51fca (diff) | |
download | gitlab-ce-8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781.tar.gz |
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'spec/frontend/global_search_input_spec.js')
-rw-r--r-- | spec/frontend/global_search_input_spec.js | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/spec/frontend/global_search_input_spec.js b/spec/frontend/global_search_input_spec.js new file mode 100644 index 00000000000..8c00ea5f193 --- /dev/null +++ b/spec/frontend/global_search_input_spec.js @@ -0,0 +1,215 @@ +/* eslint-disable no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign */ + +import $ from 'jquery'; +import '~/gl_dropdown'; +import initGlobalSearchInput from '~/global_search_input'; +import '~/lib/utils/common_utils'; + +describe('Global search input dropdown', () => { + let widget = null; + + const userName = 'root'; + + const userId = 1; + + const dashboardIssuesPath = '/dashboard/issues'; + + const dashboardMRsPath = '/dashboard/merge_requests'; + + const projectIssuesPath = '/gitlab-org/gitlab-foss/issues'; + + const projectMRsPath = '/gitlab-org/gitlab-foss/-/merge_requests'; + + const groupIssuesPath = '/groups/gitlab-org/-/issues'; + + const groupMRsPath = '/groups/gitlab-org/-/merge_requests'; + + const projectName = 'GitLab Community Edition'; + + const groupName = 'Gitlab Org'; + + const removeBodyAttributes = () => { + const $body = $('body'); + + $body.removeAttr('data-page'); + $body.removeAttr('data-project'); + $body.removeAttr('data-group'); + }; + + // Add required attributes to body before starting the test. + // section would be dashboard|group|project + const addBodyAttributes = section => { + if (section == null) { + section = 'dashboard'; + } + + const $body = $('body'); + removeBodyAttributes(); + switch (section) { + case 'dashboard': + return $body.attr('data-page', 'root:index'); + case 'group': + $body.attr('data-page', 'groups:show'); + return $body.data('group', 'gitlab-org'); + case 'project': + $body.attr('data-page', 'projects:show'); + return $body.data('project', 'gitlab-ce'); + } + }; + + const disableProjectIssues = () => { + document.querySelector('.js-search-project-options').setAttribute('data-issues-disabled', true); + }; + + // Mock `gl` object in window for dashboard specific page. App code will need it. + const mockDashboardOptions = () => { + window.gl || (window.gl = {}); + return (window.gl.dashboardOptions = { + issuesPath: dashboardIssuesPath, + mrPath: dashboardMRsPath, + }); + }; + + // Mock `gl` object in window for project specific page. App code will need it. + const mockProjectOptions = () => { + window.gl || (window.gl = {}); + return (window.gl.projectOptions = { + 'gitlab-ce': { + issuesPath: projectIssuesPath, + mrPath: projectMRsPath, + projectName, + }, + }); + }; + + const mockGroupOptions = () => { + window.gl || (window.gl = {}); + return (window.gl.groupOptions = { + 'gitlab-org': { + issuesPath: groupIssuesPath, + mrPath: groupMRsPath, + projectName: groupName, + }, + }); + }; + + const assertLinks = (list, issuesPath, mrsPath) => { + if (issuesPath) { + const issuesAssignedToMeLink = `a[href="${issuesPath}/?assignee_username=${userName}"]`; + const issuesIHaveCreatedLink = `a[href="${issuesPath}/?author_username=${userName}"]`; + + expect(list.find(issuesAssignedToMeLink).length).toBe(1); + expect(list.find(issuesAssignedToMeLink).text()).toBe('Issues assigned to me'); + expect(list.find(issuesIHaveCreatedLink).length).toBe(1); + expect(list.find(issuesIHaveCreatedLink).text()).toBe("Issues I've created"); + } + const mrsAssignedToMeLink = `a[href="${mrsPath}/?assignee_username=${userName}"]`; + const mrsIHaveCreatedLink = `a[href="${mrsPath}/?author_username=${userName}"]`; + + expect(list.find(mrsAssignedToMeLink).length).toBe(1); + expect(list.find(mrsAssignedToMeLink).text()).toBe('Merge requests assigned to me'); + expect(list.find(mrsIHaveCreatedLink).length).toBe(1); + expect(list.find(mrsIHaveCreatedLink).text()).toBe("Merge requests I've created"); + }; + + preloadFixtures('static/global_search_input.html'); + beforeEach(() => { + loadFixtures('static/global_search_input.html'); + + window.gon = {}; + window.gon.current_user_id = userId; + window.gon.current_username = userName; + + return (widget = initGlobalSearchInput()); + }); + + afterEach(() => { + // Undo what we did to the shared <body> + removeBodyAttributes(); + window.gon = {}; + }); + + it('should show Dashboard specific dropdown menu', () => { + addBodyAttributes(); + mockDashboardOptions(); + widget.searchInput.triggerHandler('focus'); + const list = widget.wrap.find('.dropdown-menu').find('ul'); + return assertLinks(list, dashboardIssuesPath, dashboardMRsPath); + }); + + it('should show Group specific dropdown menu', () => { + addBodyAttributes('group'); + mockGroupOptions(); + widget.searchInput.triggerHandler('focus'); + const list = widget.wrap.find('.dropdown-menu').find('ul'); + return assertLinks(list, groupIssuesPath, groupMRsPath); + }); + + it('should show Project specific dropdown menu', () => { + addBodyAttributes('project'); + mockProjectOptions(); + widget.searchInput.triggerHandler('focus'); + const list = widget.wrap.find('.dropdown-menu').find('ul'); + return assertLinks(list, projectIssuesPath, projectMRsPath); + }); + + it('should show only Project mergeRequest dropdown menu items when project issues are disabled', () => { + addBodyAttributes('project'); + disableProjectIssues(); + mockProjectOptions(); + widget.searchInput.triggerHandler('focus'); + const list = widget.wrap.find('.dropdown-menu').find('ul'); + assertLinks(list, null, projectMRsPath); + }); + + it('should not show category related menu if there is text in the input', () => { + addBodyAttributes('project'); + mockProjectOptions(); + widget.searchInput.val('help'); + widget.searchInput.triggerHandler('focus'); + const list = widget.wrap.find('.dropdown-menu').find('ul'); + const link = `a[href='${projectIssuesPath}/?assignee_username=${userName}']`; + + expect(list.find(link).length).toBe(0); + }); + + it('should not submit the search form when selecting an autocomplete row with the keyboard', () => { + const ENTER = 13; + const DOWN = 40; + addBodyAttributes(); + mockDashboardOptions(true); + const submitSpy = jest.spyOn(document.querySelector('form'), 'submit'); + widget.searchInput.triggerHandler('focus'); + widget.wrap.trigger($.Event('keydown', { which: DOWN })); + const enterKeyEvent = $.Event('keydown', { which: ENTER }); + widget.searchInput.trigger(enterKeyEvent); + // This does not currently catch failing behavior. For security reasons, + // browsers will not trigger default behavior (form submit, in this + // example) on JavaScript-created keypresses. + expect(submitSpy).not.toHaveBeenCalled(); + }); + + describe('disableDropdown', () => { + beforeEach(() => { + widget.enableDropdown(); + }); + + it('should close the Dropdown', () => { + const toggleSpy = jest.spyOn(widget.dropdownToggle, 'dropdown'); + + widget.dropdown.addClass('show'); + widget.disableDropdown(); + + expect(toggleSpy).toHaveBeenCalledWith('toggle'); + }); + }); + + describe('enableDropdown', () => { + it('should open the Dropdown', () => { + const toggleSpy = jest.spyOn(widget.dropdownToggle, 'dropdown'); + widget.enableDropdown(); + + expect(toggleSpy).toHaveBeenCalledWith('toggle'); + }); + }); +}); |