48ede1420d
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz> Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/12
107 lines
6.1 KiB
TypeScript
107 lines
6.1 KiB
TypeScript
import { Employee } from '../models';
|
||
import { findEmployeeByEmail, matchEmployeesByPosition, toEmployeeOption } from './employee';
|
||
|
||
// Хелпер вместо повторения company/companies в каждом литерале — в тестах
|
||
// нет нужды в разных компаниях у одного сотрудника (это отдельно проверяется
|
||
// в matchEmployeesByPosition ниже).
|
||
function emp(fio: string, email: string, position: string, company = ''): Employee {
|
||
return { fio, email, position, company, companies: company ? [company] : [] };
|
||
}
|
||
|
||
const employees: Employee[] = [
|
||
emp('Горбенко Павел', 'gorbenko.pavel@tnsu.kz', 'Разработчик middle', 'ТОО TANSU Construction'),
|
||
emp('Соколов Давид', 'sokolov.david@tnsu.kz', 'Руководитель отдела', 'ТОО TANSU Construction')
|
||
];
|
||
|
||
describe('findEmployeeByEmail', () => {
|
||
it('находит сотрудника по точному совпадению email', () => {
|
||
expect(findEmployeeByEmail(employees, 'gorbenko.pavel@tnsu.kz')?.fio).toBe('Горбенко Павел');
|
||
});
|
||
|
||
it('сравнение регистронезависимое', () => {
|
||
expect(findEmployeeByEmail(employees, 'GORBENKO.PAVEL@TNSU.KZ')?.fio).toBe('Горбенко Павел');
|
||
});
|
||
|
||
it('возвращает undefined, если email не задан', () => {
|
||
expect(findEmployeeByEmail(employees, undefined)).toBeUndefined();
|
||
expect(findEmployeeByEmail(employees, '')).toBeUndefined();
|
||
});
|
||
|
||
it('возвращает undefined, если сотрудник с таким email не найден', () => {
|
||
expect(findEmployeeByEmail(employees, 'nobody@tnsu.kz')).toBeUndefined();
|
||
});
|
||
});
|
||
|
||
describe('toEmployeeOption', () => {
|
||
it('строит опцию для SearchableSelect из сотрудника: должность и email в подписи', () => {
|
||
expect(toEmployeeOption(employees[0])).toEqual({
|
||
value: 'gorbenko.pavel@tnsu.kz',
|
||
label: 'Горбенко Павел',
|
||
sublabel: 'Разработчик middle · gorbenko.pavel@tnsu.kz'
|
||
});
|
||
});
|
||
|
||
// Должность в справочнике заполнена не у всех — тогда подпись не должна
|
||
// начинаться с висящего разделителя.
|
||
it('без должности в подписи остаётся только email', () => {
|
||
expect(toEmployeeOption(emp('Без Должности', 'nobody@tnsu.kz', ''))).toEqual({
|
||
value: 'nobody@tnsu.kz',
|
||
label: 'Без Должности',
|
||
sublabel: 'nobody@tnsu.kz'
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('matchEmployeesByPosition', () => {
|
||
const staff: Employee[] = [
|
||
emp('Плотникова Лариса', 'p@tnsu.kz', 'Генеральный директор', 'Компания А'),
|
||
emp('Самаева Асель', 's@tnsu.kz', 'Директор', 'Компания А'),
|
||
emp('Ким Николай', 'k@tnsu.kz', 'Управляющий директор', 'Компания Б'),
|
||
emp('Иванов Иван', 'i1@tnsu.kz', 'Инженер ПТО', 'Компания А'),
|
||
emp('Петров Пётр', 'i2@tnsu.kz', 'Инженер ПТО', 'Компания Б'),
|
||
emp('Без Должности', 'n@tnsu.kz', '', 'Компания А')
|
||
];
|
||
|
||
it('пустой ввод — ничего не подбирает', () => {
|
||
expect(matchEmployeesByPosition(staff, ' ')).toEqual({ exact: [], similar: [] });
|
||
});
|
||
|
||
// Бэкенд ищет точное совпадение должности, поэтому подсказка обязана считать
|
||
// так же — иначе обещала бы исполнителя там, где его не найдут.
|
||
it('точное совпадение не зависит от регистра и краевых пробелов', () => {
|
||
const result = matchEmployeesByPosition(staff, ' генеральный ДИРЕКТОР ');
|
||
expect(result.exact.map(e => e.fio)).toEqual(['Плотникова Лариса']);
|
||
});
|
||
|
||
it('одну должность в разных компаниях занимают несколько человек — возвращаются все', () => {
|
||
const result = matchEmployeesByPosition(staff, 'Инженер ПТО');
|
||
expect(result.exact.map(e => e.company)).toEqual(['Компания А', 'Компания Б']);
|
||
});
|
||
|
||
// 'директор' — сам по себе точное совпадение (должность Самаевой), а
|
||
// подстрокой входит ещё в две других — те и предлагаются похожими.
|
||
it('точное совпадение и похожие должности возвращаются одновременно', () => {
|
||
const result = matchEmployeesByPosition(staff, 'директор');
|
||
expect(result.exact.map(e => e.fio)).toEqual(['Самаева Асель']);
|
||
expect(result.similar.map(s => s.position)).toEqual(['Генеральный директор', 'Управляющий директор']);
|
||
});
|
||
|
||
// Список нужен, чтобы подставить точное написание — одинаковые строки в нём бесполезны.
|
||
it('похожие схлопываются по написанию и считают людей', () => {
|
||
expect(matchEmployeesByPosition(staff, 'инженер').similar).toEqual([
|
||
{ position: 'Инженер ПТО', fio: 'Иванов Иван', count: 2 }
|
||
]);
|
||
});
|
||
|
||
it('точное совпадение не дублируется в похожих', () => {
|
||
const result = matchEmployeesByPosition(staff, 'Директор');
|
||
expect(result.exact.map(e => e.fio)).toEqual(['Самаева Асель']);
|
||
expect(result.similar.some(s => s.position === 'Директор')).toBe(false);
|
||
});
|
||
|
||
it('сотрудники без должности не попадают в подбор', () => {
|
||
expect(matchEmployeesByPosition(staff, '').exact).toEqual([]);
|
||
expect(matchEmployeesByPosition(staff, 'директор').similar.some(s => s.position === '')).toBe(false);
|
||
});
|
||
});
|