import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import test from 'node:test'; import { decisionOptions, parseDecisionOption } from '../admin/js/views/teacher-absences.js'; test('значение мастера преобразуется в payload точечного изменения', () => { assert.deepEqual(parseDecisionOption('REPLACE_TEACHER|17'), { resolution: 'REPLACE_TEACHER', newTeacherId: 17 }); assert.deepEqual(parseDecisionOption('MOVE_TIME|2026-09-21|4'), { resolution: 'MOVE_TIME', targetLessonDate: '2026-09-21', newTimeSlotId: 4 }); assert.deepEqual(parseDecisionOption('CANCEL'), { resolution: 'CANCEL' }); }); test('мастер показывает только реально полученные кандидаты и явное отклонение', () => { const options = decisionOptions({ teacherCandidates: [{ id: 7, name: 'Петров П. П.' }], moveCandidates: [{ targetDate: '2026-09-22', timeSlotId: 3, startTime: '10:40:00', endTime: '12:10:00' }], classroomCandidates: [{ id: 9, name: 'А-201' }], cancellationAvailable: true }); assert.deepEqual(options.map(item => item.value), [ 'REPLACE_TEACHER|7', 'MOVE_TIME|2026-09-22|3', 'CHANGE_CLASSROOM|9', 'CANCEL', 'REJECT' ]); }); test('вкладка отсутствий доступна ответственным ролям и подключена к SPA', async () => { const [capabilities, main, index] = await Promise.all([ readFile(new URL('../admin/js/role-capabilities.js', import.meta.url), 'utf8'), readFile(new URL('../admin/js/main.js', import.meta.url), 'utf8'), readFile(new URL('../admin/index.html', import.meta.url), 'utf8') ]); assert.match(capabilities, /ADMIN:[\s\S]*teacher-absences/); assert.match(capabilities, /EDUCATION_OFFICE:[\s\S]*teacher-absences/); assert.match(capabilities, /DEPARTMENT:[\s\S]*teacher-absences/); assert.match(main, /'teacher-absences':[\s\S]*teacher-absences\.js/); assert.match(index, /data-tab="teacher-absences"/); });