Files
request-portal/src/webparts/requestPortal/shared/edo/edo.test.ts
T
gorbenko.pavel 637e51d7f9
Tests / frontend-test (push) Successful in 1m24s
Feature/vacation edo signing (#23)
Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/timur.gorodetskiy/request-portal/pulls/23
2026-10-05 08:53:18 +00:00

153 lines
6.7 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 { ICompany } from '../dictionary/models/ICompany';
import { IEmployeeOrganization } from '../dictionary/models/IEmployeeOrganization';
import { describeEdoError } from './edoErrors';
import { splitFio } from './fio';
import { resolveSigningTargets } from './signingTarget';
const TANSU_ID = '9de064a4-44c8-88ef-11ec-8284930fad96';
function record(overrides: Partial<IEmployeeOrganization> = {}): IEmployeeOrganization {
return {
id: 'e1',
fio: 'Иванов Иван Иванович',
email: 'ivanov@tnsu.kz',
iin: '950515123452',
company: 'ТОО TANSU Construction',
companyId: TANSU_ID,
section: '',
departmentId: '',
position: 'Инженер',
mobile: '',
...overrides
};
}
const COMPANIES: ICompany[] = [
{ Id: TANSU_ID, Name: 'ТОО TANSU Construction', Bin: '021040005165' },
{ Id: '0a1b2c3d-0000-4000-8000-000000000002', Name: 'ТОО Без БИН', Bin: '' }
];
describe('Ф.И.О. по частям для ЭДО', () => {
it('три слова', () => {
expect(splitFio('Иванов Иван Иванович')).toEqual({ lastName: 'Иванов', firstName: 'Иван', middleName: 'Иванович' });
});
it('без отчества', () => {
expect(splitFio('Иванов Иван')).toEqual({ lastName: 'Иванов', firstName: 'Иван', middleName: '' });
});
it('лишние пробелы и «оглы» не теряются', () => {
expect(splitFio(' Алиев Тимур Расул оглы ')).toEqual({
lastName: 'Алиев',
firstName: 'Тимур',
middleName: 'Расул оглы'
});
});
it('одно слово или пусто — не разобрать', () => {
expect(splitFio('Иванов')).toBeUndefined();
expect(splitFio('')).toBeUndefined();
});
});
const STROY_ID = '0a1b2c3d-0000-4000-8000-000000000003';
const NO_BIN_ID = '0a1b2c3d-0000-4000-8000-000000000002';
describe('кому и по каким компаниям отправлять на подпись', () => {
const companies: ICompany[] = [...COMPANIES, { Id: STROY_ID, Name: 'ТОО TANSU Строй', Bin: '021040005166' }];
it('ИИН из справочника сотрудников, БИН из справочника компаний', () => {
const targets = resolveSigningTargets([record()], companies);
expect(targets.iin).toBe('950515123452');
expect(targets.name.lastName).toBe('Иванов');
expect(targets.companies).toEqual([{ bin: '021040005165', name: 'ТОО TANSU Construction', position: 'Инженер' }]);
expect(targets.skipped).toEqual([]);
});
// Заявку заполняют одну, а подписывают по каждой компании, где человек работает.
it('по документу на каждую компанию, со своей должностью', () => {
const targets = resolveSigningTargets(
[record(), record({ company: 'ТОО TANSU Строй', companyId: STROY_ID, position: 'Главный инженер' })],
companies
);
expect(targets.companies).toEqual([
{ bin: '021040005165', name: 'ТОО TANSU Construction', position: 'Инженер' },
{ bin: '021040005166', name: 'ТОО TANSU Строй', position: 'Главный инженер' }
]);
});
it('одна и та же компания дважды не попадает', () => {
const targets = resolveSigningTargets([record(), record({ position: 'Совместитель' })], companies);
expect(targets.companies).toHaveLength(1);
});
it('идентификаторы компаний сравниваются без учёта регистра', () => {
expect(resolveSigningTargets([record({ companyId: TANSU_ID.toUpperCase() })], companies).companies[0].bin).toBe(
'021040005165'
);
});
it('компания без БИН не мешает остальным — уходит в пропущенные с причиной', () => {
const targets = resolveSigningTargets(
[record({ company: 'ТОО Без БИН', companyId: NO_BIN_ID }), record()],
companies
);
expect(targets.companies.map((c) => c.bin)).toEqual(['021040005165']);
expect(targets.skipped).toEqual([{ name: 'ТОО Без БИН', reason: 'в справочнике компаний нет БИН' }]);
});
it('компании нет в справочнике — тоже пропущена', () => {
const targets = resolveSigningTargets(
[record({ company: 'ТОО Неизвестная', companyId: 'ffffffff-0000-4000-8000-000000000000' })],
companies
);
expect(targets.companies).toEqual([]);
expect(targets.skipped[0].name).toBe('ТОО Неизвестная');
});
it('нет записи о сотруднике — понятная причина', () => {
expect(() => resolveSigningTargets([], companies)).toThrow('нет в кадровом справочнике');
});
it('нет ИИН в карточке', () => {
expect(() => resolveSigningTargets([record({ iin: ' ' })], companies)).toThrow('не указан ИИН');
});
it('ФИО из одного слова не годится', () => {
expect(() => resolveSigningTargets([record({ fio: 'Иванов' })], companies)).toThrow('Ф.И.О.');
});
it('ни в одной записи нет компании', () => {
expect(() => resolveSigningTargets([record({ companyId: '' })], companies)).toThrow('не указана компания');
});
});
describe('текст ошибки ЭДО', () => {
it('берёт русский detail из ProblemDetails', () => {
const body = JSON.stringify({ title: 'Bad Request', detail: 'Для компании «X» не загружен сертификат Sigex.' });
expect(describeEdoError(400, body)).toBe('Для компании «X» не загружен сертификат Sigex.');
});
it('title, если detail нет', () => {
expect(describeEdoError(400, JSON.stringify({ title: 'Подписант не найден' }))).toBe('Подписант не найден');
});
it('ошибки проверки собираются в одну строку', () => {
const body = JSON.stringify({ errors: { Iin: ['ИИН неверный'], Email: ['Email неверный', 'Слишком длинный'] } });
expect(describeEdoError(400, body)).toBe('ИИН неверный; Email неверный; Слишком длинный');
});
it('не JSON — по статусу', () => {
expect(describeEdoError(502, '<html>Bad gateway</html>')).toBe('ЭДО ответил 502');
expect(describeEdoError(401, '')).toContain('401');
expect(describeEdoError(403, '')).toContain('403');
});
});