gitlab-org--gitlab-foss/spec/frontend/users_select/test_helper.js

152 lines
4.7 KiB
JavaScript

import MockAdapter from 'axios-mock-adapter';
import { memoize, cloneDeep } from 'lodash';
import { getFixture, getJSONFixture } from 'helpers/fixtures';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import UsersSelect from '~/users_select';
// fixtures -------------------------------------------------------------------
const getUserSearchHTML = memoize((fixturePath) => {
const html = getFixture(fixturePath);
const parser = new DOMParser();
const el = parser.parseFromString(html, 'text/html').querySelector('.assignee');
return el.outerHTML;
});
const getUsersFixture = memoize(() => getJSONFixture('autocomplete/users.json'));
export const getUsersFixtureAt = (idx) => getUsersFixture()[idx];
// test context ---------------------------------------------------------------
export const createTestContext = ({ fixturePath }) => {
let mock = null;
let subject = null;
const setup = () => {
const rootEl = document.createElement('div');
rootEl.innerHTML = getUserSearchHTML(fixturePath);
document.body.appendChild(rootEl);
mock = new MockAdapter(axios);
mock.onGet('/-/autocomplete/users.json').reply(200, cloneDeep(getUsersFixture()));
};
const teardown = () => {
mock.restore();
document.body.innerHTML = '';
subject = null;
};
const createSubject = () => {
if (subject) {
throw new Error('test subject is already created');
}
subject = new UsersSelect(null);
};
return {
setup,
teardown,
createSubject,
};
};
// finders -------------------------------------------------------------------
export const findAssigneesInputs = () =>
document.querySelectorAll('input[name="merge_request[assignee_ids][]');
export const findAssigneesInputsModel = () =>
Array.from(findAssigneesInputs()).map((input) => ({
value: input.value,
dataset: { ...input.dataset },
}));
export const findUserSearchButton = () => document.querySelector('.js-user-search');
export const findDropdownItem = ({ id }) => document.querySelector(`li[data-user-id="${id}"] a`);
export const findDropdownItemsModel = () =>
Array.from(document.querySelectorAll('.dropdown-content li')).map((el) => {
if (el.classList.contains('divider')) {
return {
type: 'divider',
};
} else if (el.classList.contains('dropdown-header')) {
return {
type: 'dropdown-header',
text: el.textContent,
};
}
return {
type: 'user',
userId: el.dataset.userId,
};
});
// arrange/act helpers -------------------------------------------------------
export const setAssignees = (...users) => {
findAssigneesInputs().forEach((x) => x.remove());
const container = document.querySelector('.js-sidebar-assignee-data');
container.prepend(
...users.map((user) => {
const input = document.createElement('input');
input.name = 'merge_request[assignee_ids][]';
input.value = user.id.toString();
input.setAttribute('data-avatar-url', user.avatar_url);
input.setAttribute('data-name', user.name);
input.setAttribute('data-username', user.username);
input.setAttribute('data-can-merge', user.can_merge);
return input;
}),
);
};
export const toggleDropdown = () => findUserSearchButton().click();
export const waitForDropdownItems = async () => {
await axios.waitForAll();
await waitForPromises();
};
// assertion helpers ---------------------------------------------------------
export const createUnassignedExpectation = () => {
return [
{ type: 'user', userId: '0' },
{ type: 'divider' },
...getUsersFixture().map((x) => ({
type: 'user',
userId: x.id.toString(),
})),
];
};
export const createAssignedExpectation = ({ header, assigned }) => {
const assignedIds = new Set(assigned.map((x) => x.id));
const unassignedIds = getUsersFixture().filter((x) => !assignedIds.has(x.id));
return [
{ type: 'user', userId: '0' },
{ type: 'divider' },
{ type: 'dropdown-header', text: header },
...assigned.map((x) => ({ type: 'user', userId: x.id.toString() })),
{ type: 'divider' },
...unassignedIds.map((x) => ({ type: 'user', userId: x.id.toString() })),
];
};
export const createInputsModelExpectation = (users) =>
users.map((user) => ({
value: user.id.toString(),
dataset: {
approved: user.approved.toString(),
avatar_url: user.avatar_url,
can_merge: user.can_merge.toString(),
can_update_merge_request: user.can_update_merge_request.toString(),
id: user.id.toString(),
name: user.name,
show_status: user.show_status.toString(),
state: user.state,
username: user.username,
web_url: user.web_url,
},
}));