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); }); });