86 lines
3.4 KiB
JavaScript
86 lines
3.4 KiB
JavaScript
import assert from 'node:assert/strict';
|
||
import { readFile } from 'node:fs/promises';
|
||
import test from 'node:test';
|
||
|
||
import {
|
||
decisionOptions,
|
||
parseDecisionOption,
|
||
teacherAbsenceTeacherOptionsUrl
|
||
} 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('поиск отсутствующего преподавателя не ограничивает учебный отдел его служебной кафедрой', () => {
|
||
assert.equal(
|
||
teacherAbsenceTeacherOptionsUrl({
|
||
query: 'Иванов',
|
||
role: 'EDUCATION_OFFICE',
|
||
departmentId: 5
|
||
}),
|
||
'/api/users/teachers/options?query=%D0%98%D0%B2%D0%B0%D0%BD%D0%BE%D0%B2&limit=30'
|
||
);
|
||
assert.equal(
|
||
teacherAbsenceTeacherOptionsUrl({
|
||
query: 'Петров',
|
||
selectedId: 17,
|
||
role: 'DEPARTMENT',
|
||
departmentId: 5
|
||
}),
|
||
'/api/users/teachers/options?query=%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D0%B2&limit=30&departmentId=5&selectedId=17'
|
||
);
|
||
});
|
||
|
||
test('список преподавателей раскрывается поверх следующей карточки', async () => {
|
||
const styles = await readFile(new URL('../admin/css/teacher-absences.css', import.meta.url), 'utf8');
|
||
|
||
assert.match(styles, /\.absence-create-card\s*\{[^}]*z-index:\s*20[^}]*overflow:\s*visible/s);
|
||
assert.match(styles, /\.absence-create-card:focus-within\s*\{[^}]*z-index:\s*30/s);
|
||
});
|
||
|
||
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"/);
|
||
});
|