Задача Егора 2ч.
This commit is contained in:
151
frontend/tests/dashboard-conflicts.test.mjs
Normal file
151
frontend/tests/dashboard-conflicts.test.mjs
Normal file
@@ -0,0 +1,151 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
import {
|
||||
CONFLICT_CHECK_REASON,
|
||||
CONFLICT_CHECK_STATE,
|
||||
conflictCheckPresentation,
|
||||
currentWeekDateRange,
|
||||
formatLocalDate,
|
||||
loadDepartmentSchedules
|
||||
} from '../admin/js/dashboard-conflicts.js';
|
||||
|
||||
process.env.TZ = 'Europe/Moscow';
|
||||
|
||||
test('неделя для 2026-07-02 охватывает 2026-06-29…2026-07-05', () => {
|
||||
assert.deepEqual(
|
||||
currentWeekDateRange(new Date('2026-07-01T21:15:00Z')),
|
||||
{ startDate: '2026-06-29', endDate: '2026-07-05' }
|
||||
);
|
||||
});
|
||||
|
||||
test('неделя корректно пересекает границу года', () => {
|
||||
assert.deepEqual(
|
||||
currentWeekDateRange(new Date(2026, 0, 1, 8, 30, 0)),
|
||||
{ startDate: '2025-12-29', endDate: '2026-01-04' }
|
||||
);
|
||||
});
|
||||
|
||||
test('date-only формируется из локальных компонентов', () => {
|
||||
assert.equal(formatLocalDate(new Date('2026-01-01T21:15:00Z')), '2026-01-02');
|
||||
});
|
||||
|
||||
test('полный успех разрешает достоверный вывод по всем кафедрам', async () => {
|
||||
const result = await loadDepartmentSchedules(
|
||||
[{ id: 1 }, { id: 2 }],
|
||||
async department => [{ departmentId: department.id }]
|
||||
);
|
||||
|
||||
assert.equal(result.state, CONFLICT_CHECK_STATE.COMPLETE);
|
||||
assert.equal(result.checkedDepartmentCount, 2);
|
||||
assert.equal(result.totalDepartmentCount, 2);
|
||||
assert.deepEqual(result.lessons, [{ departmentId: 1 }, { departmentId: 2 }]);
|
||||
assert.deepEqual(result.failedDepartments, []);
|
||||
});
|
||||
|
||||
test('единичный отказ даёт частичный результат, а не пустой успешный ответ', async () => {
|
||||
const departments = [
|
||||
{ id: 1, departmentName: 'Физика' },
|
||||
{ id: 2, departmentName: 'Математика' }
|
||||
];
|
||||
const result = await loadDepartmentSchedules(departments, async department => {
|
||||
if (department.id === 2) {
|
||||
throw new Error('тестовая техническая причина');
|
||||
}
|
||||
return [{ departmentId: department.id }];
|
||||
});
|
||||
|
||||
assert.equal(result.state, CONFLICT_CHECK_STATE.PARTIAL);
|
||||
assert.equal(result.checkedDepartmentCount, 1);
|
||||
assert.deepEqual(result.lessons, [{ departmentId: 1 }]);
|
||||
assert.deepEqual(result.failedDepartments, [{ id: 2, name: 'Математика' }]);
|
||||
assert.equal('reason' in result.failedDepartments[0], false);
|
||||
});
|
||||
|
||||
test('отказ всех запросов означает, что проверка не выполнена', async () => {
|
||||
const result = await loadDepartmentSchedules(
|
||||
[{ id: 1 }, { id: 2 }],
|
||||
async () => { throw new Error('тестовый отказ'); }
|
||||
);
|
||||
|
||||
assert.equal(result.state, CONFLICT_CHECK_STATE.NOT_RUN);
|
||||
assert.equal(result.reason, CONFLICT_CHECK_REASON.ALL_REQUESTS_FAILED);
|
||||
assert.equal(result.checkedDepartmentCount, 0);
|
||||
assert.deepEqual(result.lessons, []);
|
||||
});
|
||||
|
||||
test('отсутствие кафедр не изображается как зелёная успешная проверка', async () => {
|
||||
const result = await loadDepartmentSchedules([], async () => []);
|
||||
|
||||
assert.equal(result.state, CONFLICT_CHECK_STATE.NOT_RUN);
|
||||
assert.equal(result.reason, CONFLICT_CHECK_REASON.NO_DEPARTMENTS);
|
||||
});
|
||||
|
||||
test('зелёная карточка разрешена только для полной проверки без конфликтов', () => {
|
||||
const complete = {
|
||||
state: CONFLICT_CHECK_STATE.COMPLETE,
|
||||
checkedDepartmentCount: 2,
|
||||
totalDepartmentCount: 2
|
||||
};
|
||||
const range = { startDate: '2026-06-29', endDate: '2026-07-05' };
|
||||
|
||||
assert.equal(conflictCheckPresentation(complete, 0, range).tone, 'success');
|
||||
assert.equal(conflictCheckPresentation(complete, 1, range), null);
|
||||
});
|
||||
|
||||
test('некорректный контракт результата не может породить зелёный статус', () => {
|
||||
const range = { startDate: '2026-06-29', endDate: '2026-07-05' };
|
||||
|
||||
assert.throws(
|
||||
() => conflictCheckPresentation({
|
||||
state: CONFLICT_CHECK_STATE.COMPLETE,
|
||||
checkedDepartmentCount: 1,
|
||||
totalDepartmentCount: 2
|
||||
}, 0, range),
|
||||
/Полная проверка должна охватывать все кафедры/
|
||||
);
|
||||
assert.throws(
|
||||
() => conflictCheckPresentation({
|
||||
state: CONFLICT_CHECK_STATE.COMPLETE,
|
||||
checkedDepartmentCount: 2,
|
||||
totalDepartmentCount: 2
|
||||
}, Number.NaN, range),
|
||||
/Количество конфликтов должно быть целым неотрицательным числом/
|
||||
);
|
||||
});
|
||||
|
||||
test('частичная проверка без конфликтов остаётся предупреждением', () => {
|
||||
const presentation = conflictCheckPresentation({
|
||||
state: CONFLICT_CHECK_STATE.PARTIAL,
|
||||
checkedDepartmentCount: 1,
|
||||
totalDepartmentCount: 2
|
||||
}, 0, { startDate: '2026-06-29', endDate: '2026-07-05' });
|
||||
|
||||
assert.equal(presentation.tone, 'warning');
|
||||
assert.equal(presentation.title, 'Проверка выполнена частично');
|
||||
assert.match(presentation.description, /во всём расписании нельзя/);
|
||||
});
|
||||
|
||||
test('частичная проверка с конфликтами предупреждает о неполноте результата', () => {
|
||||
const presentation = conflictCheckPresentation({
|
||||
state: CONFLICT_CHECK_STATE.PARTIAL,
|
||||
checkedDepartmentCount: 1,
|
||||
totalDepartmentCount: 3
|
||||
}, 2, { startDate: '2026-06-29', endDate: '2026-07-05' });
|
||||
|
||||
assert.equal(presentation.tone, 'warning');
|
||||
assert.match(presentation.description, /Показаны найденные конфликты/);
|
||||
});
|
||||
|
||||
test('полный отказ формирует явное состояние «Проверка не выполнена»', () => {
|
||||
const presentation = conflictCheckPresentation({
|
||||
state: CONFLICT_CHECK_STATE.NOT_RUN,
|
||||
reason: CONFLICT_CHECK_REASON.ALL_REQUESTS_FAILED,
|
||||
checkedDepartmentCount: 0,
|
||||
totalDepartmentCount: 2
|
||||
}, 0, { startDate: '2026-06-29', endDate: '2026-07-05' });
|
||||
|
||||
assert.equal(presentation.tone, 'error');
|
||||
assert.equal(presentation.title, 'Проверка не выполнена');
|
||||
assert.match(presentation.description, /Подтвердить отсутствие конфликтов нельзя/);
|
||||
});
|
||||
Reference in New Issue
Block a user