test: добавляет Vitest и CI-workflow по образцу request-portal
Покрыты чистые функции бизнес-логики: validateFeedback (обязательность полей по видам обращения, минимальная длина текста, анонимность) и getAppealFieldsConfig (согласованность конфига — обязательное поле не может быть скрыто). React-компоненты пока не тестируются: сначала нужно решить, куда форма отправляет данные, иначе тесты придётся сразу переписывать. vite.config.ts: defineConfig теперь из 'vitest/config' — один файл конфига на сборку и тесты вместо двух рассинхронизирующихся. globals: true и environment: 'node', т.к. тестируется логика, а не DOM. .gitea/workflows/test.yml — тот же принцип, что в request-portal (push в main, PR, ретраи npm install), но npm run ci вместо heft test: здесь нет SPFx/Jest, и деплой пока не добавлен — куда разворачивать dist/, не решено. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { COMPANY_OPTIONS, getAppealFieldsConfig } from './model';
|
||||
|
||||
// Форма (AppealSection) и валидация (validateFeedback) читают одно и то же
|
||||
// правило из getAppealFieldsConfig — если оно разойдётся, форма и валидация
|
||||
// начнут спорить друг с другом. Эти тесты фиксируют контракт правила.
|
||||
describe('getAppealFieldsConfig', () => {
|
||||
it('жалоба: описание обязательно, предложение показано, но необязательно', () => {
|
||||
const fields = getAppealFieldsConfig('complaint');
|
||||
expect(fields.situation).toEqual({ visible: true, required: true });
|
||||
expect(fields.suggestion).toEqual({ visible: true, required: false });
|
||||
});
|
||||
|
||||
it('предложение: описания ситуации нет вовсе, само предложение обязательно', () => {
|
||||
const fields = getAppealFieldsConfig('suggestion');
|
||||
expect(fields.situation).toEqual({ visible: false, required: false });
|
||||
expect(fields.suggestion).toEqual({ visible: true, required: true });
|
||||
});
|
||||
|
||||
it('другое: обязательно только описание, предложения не показываем', () => {
|
||||
const fields = getAppealFieldsConfig('other');
|
||||
expect(fields.situation).toEqual({ visible: true, required: true });
|
||||
expect(fields.suggestion).toEqual({ visible: false, required: false });
|
||||
});
|
||||
|
||||
it('обязательное поле не может быть скрыто ни для одного вида обращения', () => {
|
||||
// Форма не сможет попросить исправить поле, которого не видно на экране —
|
||||
// required: true при visible: false — это несогласованная настройка.
|
||||
(['complaint', 'suggestion', 'other'] as const).forEach((kind) => {
|
||||
const fields = getAppealFieldsConfig(kind);
|
||||
expect(fields.situation.required && !fields.situation.visible).toBe(false);
|
||||
expect(fields.suggestion.required && !fields.suggestion.visible).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Справочник компаний используется бэкендом по Id (см. комментарий в model.ts) —
|
||||
// дубликат Id незаметно перепутал бы два разных юрлица.
|
||||
describe('COMPANY_OPTIONS', () => {
|
||||
it('не содержит повторяющихся Id', () => {
|
||||
const ids = COMPANY_OPTIONS.map((option) => option.value);
|
||||
expect(new Set(ids).size).toBe(ids.length);
|
||||
});
|
||||
|
||||
it('у каждой компании есть непустое название', () => {
|
||||
COMPANY_OPTIONS.forEach((option) => {
|
||||
expect(option.label.trim().length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user