комит
This commit is contained in:
29
frontend/tests/academic-calendar-grid.test.mjs
Normal file
29
frontend/tests/academic-calendar-grid.test.mjs
Normal file
@@ -0,0 +1,29 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { academicCalendarWeekNumber } from '../admin/js/views/academic-calendar-grid.js';
|
||||
|
||||
test('в 2026 году первая неделя оставляет понедельник перед 1 сентября пустым', () => {
|
||||
const yearStart = '2026-09-01';
|
||||
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2026-09-01'), 1);
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2026-09-06'), 1);
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2026-09-07'), 2);
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2026-09-14'), 3);
|
||||
});
|
||||
|
||||
test('в 2027 году первая неделя оставляет понедельник и вторник перед 1 сентября пустыми', () => {
|
||||
const yearStart = '2027-09-01';
|
||||
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2027-09-01'), 1);
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2027-09-05'), 1);
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2027-09-06'), 2);
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2027-09-13'), 3);
|
||||
});
|
||||
|
||||
test('учебный год с понедельника сохраняет полную первую неделю', () => {
|
||||
const yearStart = '2025-09-01';
|
||||
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2025-09-07'), 1);
|
||||
assert.equal(academicCalendarWeekNumber(yearStart, '2025-09-08'), 2);
|
||||
});
|
||||
31
frontend/tests/academic-calendar-title.test.mjs
Normal file
31
frontend/tests/academic-calendar-title.test.mjs
Normal file
@@ -0,0 +1,31 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { buildAcademicCalendarTitle } from '../admin/js/views/academic-calendar-title.js';
|
||||
|
||||
test('название календарного графика собирается в заданном порядке', () => {
|
||||
assert.equal(buildAcademicCalendarTitle({
|
||||
specialtyCode: '09.03.04',
|
||||
specialtyProfileName: 'Программная инженерия',
|
||||
studyFormName: 'Очная',
|
||||
academicYearTitle: '2025-2026'
|
||||
}), '09.03.04 — Программная инженерия — Очная — 2025-2026');
|
||||
});
|
||||
|
||||
test('части названия очищаются от лишних пробелов', () => {
|
||||
assert.equal(buildAcademicCalendarTitle({
|
||||
specialtyCode: ' 09.03.04 ',
|
||||
specialtyProfileName: ' Без профиля ',
|
||||
studyFormName: ' Заочная ',
|
||||
academicYearTitle: ' 2026-2027 '
|
||||
}), '09.03.04 — Без профиля — Заочная — 2026-2027');
|
||||
});
|
||||
|
||||
test('неполный набор полей не образует вводящее в заблуждение название', () => {
|
||||
assert.equal(buildAcademicCalendarTitle({
|
||||
specialtyCode: '09.03.04',
|
||||
specialtyProfileName: '',
|
||||
studyFormName: 'Очная',
|
||||
academicYearTitle: '2025-2026'
|
||||
}), '');
|
||||
});
|
||||
37
frontend/tests/academic-calendar-tooltip.test.mjs
Normal file
37
frontend/tests/academic-calendar-tooltip.test.mjs
Normal file
@@ -0,0 +1,37 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { calculateCalendarTooltipPosition } from '../admin/js/views/academic-calendar.js';
|
||||
|
||||
test('подсказка располагается с отступом справа и снизу от курсора', () => {
|
||||
assert.deepEqual(calculateCalendarTooltipPosition({
|
||||
pointerX: 100,
|
||||
pointerY: 80,
|
||||
tooltipWidth: 280,
|
||||
tooltipHeight: 160,
|
||||
viewportWidth: 1280,
|
||||
viewportHeight: 720
|
||||
}), { left: 114, top: 94 });
|
||||
});
|
||||
|
||||
test('у правого нижнего края подсказка раскрывается влево и вверх', () => {
|
||||
assert.deepEqual(calculateCalendarTooltipPosition({
|
||||
pointerX: 1260,
|
||||
pointerY: 700,
|
||||
tooltipWidth: 280,
|
||||
tooltipHeight: 160,
|
||||
viewportWidth: 1280,
|
||||
viewportHeight: 720
|
||||
}), { left: 966, top: 526 });
|
||||
});
|
||||
|
||||
test('подсказка не выходит за минимальные отступы узкого viewport', () => {
|
||||
assert.deepEqual(calculateCalendarTooltipPosition({
|
||||
pointerX: 190,
|
||||
pointerY: 110,
|
||||
tooltipWidth: 176,
|
||||
tooltipHeight: 96,
|
||||
viewportWidth: 200,
|
||||
viewportHeight: 120
|
||||
}), { left: 12, top: 12 });
|
||||
});
|
||||
91
frontend/tests/date-input.test.mjs
Normal file
91
frontend/tests/date-input.test.mjs
Normal file
@@ -0,0 +1,91 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import test from 'node:test';
|
||||
|
||||
import {
|
||||
bindDateInputMask,
|
||||
dateInputValueToIso,
|
||||
formatDateInputValue,
|
||||
isoDateToInputValue
|
||||
} from '../admin/js/date-input.js';
|
||||
|
||||
test('маска расставляет точки при последовательном вводе восьми цифр', () => {
|
||||
assert.equal(formatDateInputValue('0'), '0');
|
||||
assert.equal(formatDateInputValue('01'), '01');
|
||||
assert.equal(formatDateInputValue('010'), '01.0');
|
||||
assert.equal(formatDateInputValue('0109'), '01.09');
|
||||
assert.equal(formatDateInputValue('01092'), '01.09.2');
|
||||
assert.equal(formatDateInputValue('01092026'), '01.09.2026');
|
||||
});
|
||||
|
||||
test('маска удаляет посторонние символы и ограничивает год четырьмя цифрами', () => {
|
||||
assert.equal(formatDateInputValue('01-09/2026'), '01.09.2026');
|
||||
assert.equal(formatDateInputValue('010920261234'), '01.09.2026');
|
||||
});
|
||||
|
||||
test('привязанная маска расставляет точки прямо во время ввода', () => {
|
||||
const input = new DateInputStub();
|
||||
bindDateInputMask(input);
|
||||
|
||||
typeText(input, '01092026');
|
||||
assert.equal(input.value, '01.09.2026');
|
||||
assert.equal(input.selectionStart, 10);
|
||||
|
||||
typeText(input, '12');
|
||||
assert.equal(input.value, '01.09.2026');
|
||||
assert.equal(input.selectionStart, 10);
|
||||
});
|
||||
|
||||
test('дата преобразуется между форматом поля и ISO без потери значения', () => {
|
||||
assert.equal(dateInputValueToIso('01.09.2026'), '2026-09-01');
|
||||
assert.equal(isoDateToInputValue('2026-09-01'), '01.09.2026');
|
||||
});
|
||||
|
||||
test('неполный, шестизначный год и несуществующие даты отклоняются', () => {
|
||||
assert.throws(() => dateInputValueToIso('01.09.202'), /год — 4 цифры/);
|
||||
assert.throws(() => dateInputValueToIso('01.09.202612'), /год — 4 цифры/);
|
||||
assert.throws(() => dateInputValueToIso('31.02.2026'), /существующую дату/);
|
||||
assert.equal(dateInputValueToIso('29.02.2024'), '2024-02-29');
|
||||
assert.throws(() => dateInputValueToIso('29.02.2025'), /существующую дату/);
|
||||
});
|
||||
|
||||
test('все поля дат календарного графика подключены к числовой маске', async () => {
|
||||
const template = await readFile(new URL('../admin/views/academic-calendar.html', import.meta.url), 'utf8');
|
||||
assert.equal(template.match(/\bdata-date-input\b/g)?.length, 6);
|
||||
assert.equal(template.match(/\bmaxlength="10"/g)?.length, 6);
|
||||
assert.doesNotMatch(template, /type="date"/);
|
||||
});
|
||||
|
||||
class DateInputStub extends EventTarget {
|
||||
constructor() {
|
||||
super();
|
||||
this.value = '';
|
||||
this.selectionStart = 0;
|
||||
this.selectionEnd = 0;
|
||||
this.form = null;
|
||||
}
|
||||
|
||||
setSelectionRange(start, end) {
|
||||
this.selectionStart = start;
|
||||
this.selectionEnd = end;
|
||||
}
|
||||
|
||||
setCustomValidity() {}
|
||||
|
||||
setAttribute() {}
|
||||
|
||||
removeAttribute() {}
|
||||
|
||||
focus() {}
|
||||
}
|
||||
|
||||
function typeText(input, text) {
|
||||
for (const character of text) {
|
||||
const start = input.selectionStart;
|
||||
const end = input.selectionEnd;
|
||||
input.value = input.value.slice(0, start) + character + input.value.slice(end);
|
||||
input.selectionStart = start + 1;
|
||||
input.selectionEnd = start + 1;
|
||||
input.dispatchEvent(new Event('input'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user