refactor: split calendar page components
This commit is contained in:
96
webui/tests/calendar-view-model.test.ts
Normal file
96
webui/tests/calendar-view-model.test.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import {
|
||||
continuousVirtualWindow,
|
||||
groupEventsByDay,
|
||||
layoutTimedEventsForDay,
|
||||
moveEventToDay,
|
||||
rangeForMode,
|
||||
resizeEventToTime,
|
||||
} from "../src/features/calendar/calendarViewModel.ts";
|
||||
|
||||
function assert(condition: unknown, message: string): void {
|
||||
if (!condition) throw new Error(message);
|
||||
}
|
||||
|
||||
function event(
|
||||
id: string,
|
||||
start: Date,
|
||||
end: Date,
|
||||
allDay = false,
|
||||
) {
|
||||
return {
|
||||
id,
|
||||
calendar_id: "calendar-1",
|
||||
summary: id,
|
||||
start_at: start.toISOString(),
|
||||
end_at: end.toISOString(),
|
||||
all_day: allDay,
|
||||
} as never;
|
||||
}
|
||||
|
||||
const focus = new Date(2026, 6, 15, 12);
|
||||
const month = rangeForMode("month", focus, {
|
||||
before: 8,
|
||||
after: 12,
|
||||
});
|
||||
assert(
|
||||
(month.end.getTime() - month.start.getTime()) / 86_400_000 === 42,
|
||||
"month view should retain its six-week window",
|
||||
);
|
||||
|
||||
const virtual = continuousVirtualWindow(
|
||||
100,
|
||||
{ scrollTop: 20 * 92, height: 8 * 92 },
|
||||
3,
|
||||
);
|
||||
assert(virtual.start === 17, "virtualization should retain overscan above");
|
||||
assert(virtual.end === 31, "virtualization should retain overscan below");
|
||||
assert(
|
||||
virtual.topSpacerHeight + virtual.bottomSpacerHeight > 0,
|
||||
"virtualization should preserve offscreen geometry",
|
||||
);
|
||||
|
||||
const day = new Date(2026, 6, 7);
|
||||
const parallel = [0, 1, 2, 3].map((index) =>
|
||||
event(
|
||||
`event-${index}`,
|
||||
new Date(2026, 6, 7, 9),
|
||||
new Date(2026, 6, 7, 10),
|
||||
),
|
||||
);
|
||||
const layout = layoutTimedEventsForDay(parallel, day);
|
||||
assert(
|
||||
layout.items.length === 2 && layout.overflows.length === 1,
|
||||
"parallel events should use bounded columns plus one overflow control",
|
||||
);
|
||||
assert(
|
||||
layout.overflows[0].events.length === 2,
|
||||
"overflow should retain every hidden event",
|
||||
);
|
||||
|
||||
const allDay = event(
|
||||
"all-day",
|
||||
new Date(2026, 6, 7),
|
||||
new Date(2026, 6, 9),
|
||||
true,
|
||||
);
|
||||
const grouped = groupEventsByDay([allDay]);
|
||||
assert(grouped.size === 2, "all-day end dates should remain exclusive");
|
||||
const moved = moveEventToDay(allDay, new Date(2026, 6, 20));
|
||||
assert(
|
||||
moved.endAt?.getDate() === 22,
|
||||
"moving an all-day event should preserve its duration",
|
||||
);
|
||||
|
||||
const timed = event(
|
||||
"timed",
|
||||
new Date(2026, 6, 7, 10),
|
||||
new Date(2026, 6, 7, 11),
|
||||
);
|
||||
const resized = resizeEventToTime(timed, "end", day, 9 * 60);
|
||||
assert(
|
||||
resized.endAt !== null &&
|
||||
resized.endAt.getTime() > resized.startAt.getTime(),
|
||||
"resizing must not invert an event",
|
||||
);
|
||||
|
||||
console.log("Calendar view model interaction checks passed.");
|
||||
Reference in New Issue
Block a user