Files
tnsu-approval-route/frontend/src/webparts/approvalAdmin/utils/employee.test.ts
T
gorbenko.pavel 48ede1420d
Tests / backend-test (push) Successful in 1m38s
Tests / frontend-test (push) Successful in 47s
Обходной лист (#12)
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/12
2026-08-17 05:43:52 +00:00

107 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
});
});