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

285 lines
9.2 KiB
JavaScript
Raw Normal View History

2019-12-26 22:10:19 +05:30
/* eslint-disable no-unused-expressions, consistent-return, no-param-reassign, default-case, no-return-assign */
2016-09-13 17:45:13 +05:30
2018-05-09 12:01:36 +05:30
import $ from 'jquery';
2017-09-10 17:25:29 +05:30
import '~/gl_dropdown';
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';
2020-07-28 23:09:34 +05:30
import axios from '~/lib/utils/axios_utils';
import AxiosMockAdapter from 'axios-mock-adapter';
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 = () => {
2018-03-17 18:26:18 +05:30
const $body = $('body');
$body.removeAttr('data-page');
$body.removeAttr('data-project');
$body.removeAttr('data-group');
};
2016-09-29 09:46:39 +05:30
// Add required attributes to body before starting the test.
// section would be dashboard|group|project
2020-06-23 00:09:42 +05:30
const addBodyAttributes = section => {
2016-09-13 17:45:13 +05:30
if (section == null) {
section = 'dashboard';
}
2018-03-17 18:26:18 +05:30
const $body = $('body');
removeBodyAttributes();
2016-09-13 17:45:13 +05:30
switch (section) {
case 'dashboard':
2018-03-17 18:26:18 +05:30
return $body.attr('data-page', 'root:index');
2016-09-13 17:45:13 +05:30
case 'group':
2018-03-17 18:26:18 +05:30
$body.attr('data-page', 'groups:show');
2016-09-13 17:45:13 +05:30
return $body.data('group', 'gitlab-org');
case 'project':
2018-03-17 18:26:18 +05:30
$body.attr('data-page', 'projects:show');
2016-09-13 17:45:13 +05:30
return $body.data('project', 'gitlab-ce');
}
};
2020-06-23 00:09:42 +05:30
const disableProjectIssues = () => {
2018-03-17 18:26:18 +05:30
document.querySelector('.js-search-project-options').setAttribute('data-issues-disabled', true);
};
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 = () => {
2016-09-13 17:45:13 +05:30
window.gl || (window.gl = {});
2018-05-09 12:01:36 +05:30
return (window.gl.dashboardOptions = {
2016-09-13 17:45:13 +05:30
issuesPath: dashboardIssuesPath,
2018-05-09 12:01:36 +05:30
mrPath: dashboardMRsPath,
});
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 = () => {
2016-09-13 17:45:13 +05:30
window.gl || (window.gl = {});
2018-05-09 12:01:36 +05:30
return (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
},
});
2016-09-13 17:45:13 +05:30
};
2020-06-23 00:09:42 +05:30
const mockGroupOptions = () => {
2016-09-13 17:45:13 +05:30
window.gl || (window.gl = {});
2018-05-09 12:01:36 +05:30
return (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,
},
});
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-07-28 23:09:34 +05:30
preloadFixtures('static/search_autocomplete.html');
2020-06-23 00:09:42 +05:30
beforeEach(() => {
2020-07-28 23:09:34 +05:30
loadFixtures('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
2020-07-28 23:09:34 +05:30
return (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 = {};
});
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() {
return new Promise(resolve => {
const dropdown = widget.searchInput.data('glDropdown');
const filterCallback = dropdown.filter.options.callback;
dropdown.filter.options.callback = jest.fn(data => {
filterCallback(data);
resolve();
});
widget.searchInput.val('Gitlab');
widget.searchInput.triggerHandler('input');
});
}
it('suggest Projects', done => {
// eslint-disable-next-line promise/catch-or-return
triggerAutocomplete().finally(() => {
const list = widget.wrap.find('.dropdown-menu').find('ul');
const link = "a[href$='/gitlab-org/gitlab-test']";
expect(list.find(link).length).toBe(1);
done();
});
// Make sure jest properly acknowledge the `done` invocation
jest.runOnlyPendingTimers();
});
it('suggest Groups', done => {
// eslint-disable-next-line promise/catch-or-return
triggerAutocomplete().finally(() => {
const list = widget.wrap.find('.dropdown-menu').find('ul');
const link = "a[href$='/gitlab-org']";
expect(list.find(link).length).toBe(1);
done();
});
// Make sure jest properly acknowledge the `done` invocation
jest.runOnlyPendingTimers();
});
});
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-06-23 00:09:42 +05:30
it('should open the Dropdown', () => {
const toggleSpy = jest.spyOn(widget.dropdownToggle, 'dropdown');
2020-07-28 23:09:34 +05:30
widget.enableAutocomplete();
2020-05-24 23:13:21 +05:30
expect(toggleSpy).toHaveBeenCalledWith('toggle');
});
});
2018-05-09 12:01:36 +05:30
});