debian-mirror-gitlab/spec/frontend/search_autocomplete_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

293 lines
9.1 KiB
JavaScript
Raw Normal View History

2020-10-24 23:57:45 +05:30
import AxiosMockAdapter from 'axios-mock-adapter';
2021-03-11 19:13:27 +05:30
import $ from 'jquery';
2022-07-16 23:28:13 +05:30
import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
2020-10-24 23:57:45 +05:30
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
2021-03-11 19:13:27 +05:30
import axios from '~/lib/utils/axios_utils';
2020-07-28 23:09:34 +05:30
import initSearchAutocomplete from '~/search_autocomplete';
2017-09-10 17:25:29 +05:30
import '~/lib/utils/common_utils';
2016-09-13 17:45:13 +05:30
2020-07-28 23:09:34 +05:30
describe('Search autocomplete dropdown', () => {
2019-12-26 22:10:19 +05:30
let widget = null;
2016-09-13 17:45:13 +05:30
2019-12-26 22:10:19 +05:30
const userName = 'root';
const userId = 1;
const dashboardIssuesPath = '/dashboard/issues';
const dashboardMRsPath = '/dashboard/merge_requests';
const projectIssuesPath = '/gitlab-org/gitlab-foss/issues';
2020-03-13 15:44:24 +05:30
const projectMRsPath = '/gitlab-org/gitlab-foss/-/merge_requests';
const groupIssuesPath = '/groups/gitlab-org/-/issues';
const groupMRsPath = '/groups/gitlab-org/-/merge_requests';
2020-07-28 23:09:34 +05:30
const autocompletePath = '/search/autocomplete';
2019-12-26 22:10:19 +05:30
const projectName = 'GitLab Community Edition';
const groupName = 'Gitlab Org';
2016-09-13 17:45:13 +05:30
2020-06-23 00:09:42 +05:30
const removeBodyAttributes = () => {
2021-09-30 23:02:18 +05:30
const { body } = document;
2018-03-17 18:26:18 +05:30
2021-09-30 23:02:18 +05:30
delete body.dataset.page;
delete body.dataset.project;
delete body.dataset.group;
2018-03-17 18:26:18 +05:30
};
2016-09-29 09:46:39 +05:30
// Add required attributes to body before starting the test.
// section would be dashboard|group|project
2021-09-30 23:02:18 +05:30
const addBodyAttributes = (section = 'dashboard') => {
2018-03-17 18:26:18 +05:30
removeBodyAttributes();
2021-09-30 23:02:18 +05:30
const { body } = document;
2016-09-13 17:45:13 +05:30
switch (section) {
case 'dashboard':
2021-09-30 23:02:18 +05:30
body.dataset.page = 'root:index';
break;
2016-09-13 17:45:13 +05:30
case 'group':
2021-09-30 23:02:18 +05:30
body.dataset.page = 'groups:show';
body.dataset.group = 'gitlab-org';
break;
2016-09-13 17:45:13 +05:30
case 'project':
2021-09-30 23:02:18 +05:30
body.dataset.page = 'projects:show';
body.dataset.project = 'gitlab-ce';
break;
default:
break;
2016-09-13 17:45:13 +05:30
}
};
2020-06-23 00:09:42 +05:30
const disableProjectIssues = () => {
2022-07-23 23:45:48 +05:30
document.querySelector('.js-search-project-options').dataset.issuesDisabled = true;
2018-03-17 18:26:18 +05:30
};
2016-09-29 09:46:39 +05:30
// Mock `gl` object in window for dashboard specific page. App code will need it.
2020-06-23 00:09:42 +05:30
const mockDashboardOptions = () => {
2021-09-30 23:02:18 +05:30
window.gl.dashboardOptions = {
2016-09-13 17:45:13 +05:30
issuesPath: dashboardIssuesPath,
2018-05-09 12:01:36 +05:30
mrPath: dashboardMRsPath,
2021-09-30 23:02:18 +05:30
};
2016-09-13 17:45:13 +05:30
};
2016-09-29 09:46:39 +05:30
// Mock `gl` object in window for project specific page. App code will need it.
2020-06-23 00:09:42 +05:30
const mockProjectOptions = () => {
2021-09-30 23:02:18 +05:30
window.gl.projectOptions = {
2016-09-13 17:45:13 +05:30
'gitlab-ce': {
issuesPath: projectIssuesPath,
mrPath: projectMRsPath,
2019-12-04 20:38:33 +05:30
projectName,
2018-05-09 12:01:36 +05:30
},
2021-09-30 23:02:18 +05:30
};
2016-09-13 17:45:13 +05:30
};
2020-06-23 00:09:42 +05:30
const mockGroupOptions = () => {
2021-09-30 23:02:18 +05:30
window.gl.groupOptions = {
2016-09-13 17:45:13 +05:30
'gitlab-org': {
issuesPath: groupIssuesPath,
mrPath: groupMRsPath,
2018-05-09 12:01:36 +05:30
projectName: groupName,
},
2021-09-30 23:02:18 +05:30
};
2016-09-13 17:45:13 +05:30
};
2020-06-23 00:09:42 +05:30
const assertLinks = (list, issuesPath, mrsPath) => {
2018-03-17 18:26:18 +05:30
if (issuesPath) {
2019-02-15 15:39:39 +05:30
const issuesAssignedToMeLink = `a[href="${issuesPath}/?assignee_username=${userName}"]`;
const issuesIHaveCreatedLink = `a[href="${issuesPath}/?author_username=${userName}"]`;
2018-12-13 13:39:08 +05:30
2018-05-09 12:01:36 +05:30
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");
2018-03-17 18:26:18 +05:30
}
2019-02-15 15:39:39 +05:30
const mrsAssignedToMeLink = `a[href="${mrsPath}/?assignee_username=${userName}"]`;
const mrsIHaveCreatedLink = `a[href="${mrsPath}/?author_username=${userName}"]`;
2018-12-13 13:39:08 +05:30
2018-05-09 12:01:36 +05:30
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");
2016-09-13 17:45:13 +05:30
};
2020-06-23 00:09:42 +05:30
beforeEach(() => {
2022-07-16 23:28:13 +05:30
loadHTMLFixture('static/search_autocomplete.html');
2018-03-17 18:26:18 +05:30
2018-05-09 12:01:36 +05:30
window.gon = {};
window.gon.current_user_id = userId;
window.gon.current_username = userName;
2020-07-28 23:09:34 +05:30
window.gl = window.gl || (window.gl = {});
2017-08-17 22:00:37 +05:30
2021-09-30 23:02:18 +05:30
widget = initSearchAutocomplete({ autocompletePath });
2018-05-09 12:01:36 +05:30
});
2017-08-17 22:00:37 +05:30
2020-06-23 00:09:42 +05:30
afterEach(() => {
2018-05-09 12:01:36 +05:30
// Undo what we did to the shared <body>
removeBodyAttributes();
window.gon = {};
2022-07-16 23:28:13 +05:30
resetHTMLFixture();
2018-05-09 12:01:36 +05:30
});
2018-12-13 13:39:08 +05:30
2020-06-23 00:09:42 +05:30
it('should show Dashboard specific dropdown menu', () => {
2018-05-09 12:01:36 +05:30
addBodyAttributes();
mockDashboardOptions();
widget.searchInput.triggerHandler('focus');
2019-12-26 22:10:19 +05:30
const list = widget.wrap.find('.dropdown-menu').find('ul');
2018-05-09 12:01:36 +05:30
return assertLinks(list, dashboardIssuesPath, dashboardMRsPath);
});
2018-12-13 13:39:08 +05:30
2020-06-23 00:09:42 +05:30
it('should show Group specific dropdown menu', () => {
2018-05-09 12:01:36 +05:30
addBodyAttributes('group');
mockGroupOptions();
widget.searchInput.triggerHandler('focus');
2019-12-26 22:10:19 +05:30
const list = widget.wrap.find('.dropdown-menu').find('ul');
2018-05-09 12:01:36 +05:30
return assertLinks(list, groupIssuesPath, groupMRsPath);
});
2018-12-13 13:39:08 +05:30
2020-06-23 00:09:42 +05:30
it('should show Project specific dropdown menu', () => {
2018-05-09 12:01:36 +05:30
addBodyAttributes('project');
mockProjectOptions();
widget.searchInput.triggerHandler('focus');
2019-12-26 22:10:19 +05:30
const list = widget.wrap.find('.dropdown-menu').find('ul');
2018-05-09 12:01:36 +05:30
return assertLinks(list, projectIssuesPath, projectMRsPath);
});
2018-12-13 13:39:08 +05:30
2020-06-23 00:09:42 +05:30
it('should show only Project mergeRequest dropdown menu items when project issues are disabled', () => {
2018-05-09 12:01:36 +05:30
addBodyAttributes('project');
disableProjectIssues();
mockProjectOptions();
widget.searchInput.triggerHandler('focus');
const list = widget.wrap.find('.dropdown-menu').find('ul');
assertLinks(list, null, projectMRsPath);
});
2018-12-13 13:39:08 +05:30
2020-06-23 00:09:42 +05:30
it('should not show category related menu if there is text in the input', () => {
2018-05-09 12:01:36 +05:30
addBodyAttributes('project');
mockProjectOptions();
widget.searchInput.val('help');
widget.searchInput.triggerHandler('focus');
2019-12-26 22:10:19 +05:30
const list = widget.wrap.find('.dropdown-menu').find('ul');
const link = `a[href='${projectIssuesPath}/?assignee_username=${userName}']`;
2018-12-13 13:39:08 +05:30
expect(list.find(link).length).toBe(0);
2018-05-09 12:01:36 +05:30
});
2018-12-13 13:39:08 +05:30
2020-06-23 00:09:42 +05:30
it('should not submit the search form when selecting an autocomplete row with the keyboard', () => {
2019-12-26 22:10:19 +05:30
const ENTER = 13;
const DOWN = 40;
2018-05-09 12:01:36 +05:30
addBodyAttributes();
mockDashboardOptions(true);
2020-06-23 00:09:42 +05:30
const submitSpy = jest.spyOn(document.querySelector('form'), 'submit');
2018-05-09 12:01:36 +05:30
widget.searchInput.triggerHandler('focus');
widget.wrap.trigger($.Event('keydown', { which: DOWN }));
2019-12-26 22:10:19 +05:30
const enterKeyEvent = $.Event('keydown', { which: ENTER });
2018-05-09 12:01:36 +05:30
widget.searchInput.trigger(enterKeyEvent);
2020-07-28 23:09:34 +05:30
2018-05-09 12:01:36 +05:30
// 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.
2020-06-23 00:09:42 +05:30
expect(submitSpy).not.toHaveBeenCalled();
2016-09-13 17:45:13 +05:30
});
2020-05-24 23:13:21 +05:30
2020-07-28 23:09:34 +05:30
describe('show autocomplete results', () => {
beforeEach(() => {
widget.enableAutocomplete();
const axiosMock = new AxiosMockAdapter(axios);
const autocompleteUrl = new RegExp(autocompletePath);
axiosMock.onGet(autocompleteUrl).reply(200, [
{
category: 'Projects',
id: 1,
value: 'Gitlab Test',
label: 'Gitlab Org / Gitlab Test',
url: '/gitlab-org/gitlab-test',
avatar_url: '',
},
{
category: 'Groups',
id: 1,
value: 'Gitlab Org',
label: 'Gitlab Org',
url: '/gitlab-org',
avatar_url: '',
},
]);
});
function triggerAutocomplete() {
2021-03-08 18:12:59 +05:30
return new Promise((resolve) => {
2020-11-24 15:15:51 +05:30
const dropdown = widget.searchInput.data('deprecatedJQueryDropdown');
2020-07-28 23:09:34 +05:30
const filterCallback = dropdown.filter.options.callback;
2021-03-08 18:12:59 +05:30
dropdown.filter.options.callback = jest.fn((data) => {
2020-07-28 23:09:34 +05:30
filterCallback(data);
resolve();
});
widget.searchInput.val('Gitlab');
widget.searchInput.triggerHandler('input');
});
}
2022-06-21 17:19:12 +05:30
it('suggest Projects', async () => {
await triggerAutocomplete();
2020-07-28 23:09:34 +05:30
2022-06-21 17:19:12 +05:30
const list = widget.wrap.find('.dropdown-menu').find('ul');
const link = "a[href$='/gitlab-org/gitlab-test']";
2020-07-28 23:09:34 +05:30
2022-06-21 17:19:12 +05:30
expect(list.find(link).length).toBe(1);
2020-07-28 23:09:34 +05:30
});
2022-06-21 17:19:12 +05:30
it('suggest Groups', async () => {
await triggerAutocomplete();
2020-07-28 23:09:34 +05:30
2022-06-21 17:19:12 +05:30
const list = widget.wrap.find('.dropdown-menu').find('ul');
const link = "a[href$='/gitlab-org']";
2020-07-28 23:09:34 +05:30
2022-06-21 17:19:12 +05:30
expect(list.find(link).length).toBe(1);
2020-07-28 23:09:34 +05:30
});
});
describe('disableAutocomplete', () => {
2020-06-23 00:09:42 +05:30
beforeEach(() => {
2020-07-28 23:09:34 +05:30
widget.enableAutocomplete();
2020-05-24 23:13:21 +05:30
});
2020-06-23 00:09:42 +05:30
it('should close the Dropdown', () => {
const toggleSpy = jest.spyOn(widget.dropdownToggle, 'dropdown');
2020-05-24 23:13:21 +05:30
widget.dropdown.addClass('show');
2020-07-28 23:09:34 +05:30
widget.disableAutocomplete();
2020-05-24 23:13:21 +05:30
expect(toggleSpy).toHaveBeenCalledWith('toggle');
});
});
2020-07-28 23:09:34 +05:30
describe('enableAutocomplete', () => {
2020-10-24 23:57:45 +05:30
let toggleSpy;
let trackingSpy;
beforeEach(() => {
toggleSpy = jest.spyOn(widget.dropdownToggle, 'dropdown');
trackingSpy = mockTracking('_category_', undefined, jest.spyOn);
document.body.dataset.page = 'some:page'; // default tracking for category
});
afterEach(() => {
unmockTracking();
});
2020-06-23 00:09:42 +05:30
it('should open the Dropdown', () => {
2020-07-28 23:09:34 +05:30
widget.enableAutocomplete();
2020-05-24 23:13:21 +05:30
expect(toggleSpy).toHaveBeenCalledWith('toggle');
});
2020-10-24 23:57:45 +05:30
it('should track the opening', () => {
widget.enableAutocomplete();
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_search_bar', {
label: 'main_navigation',
property: 'navigation',
});
});
2020-05-24 23:13:21 +05:30
});
2018-05-09 12:01:36 +05:30
});