c2e4467dd8
- Merkliste zusaetzlich im Arbeitsspeicher (sonst alle 10 s dieselbe Meldung) - Aendern der Faelligkeit atomar gegen gleichzeitiges Faelligwerden, setzt Mail-Spur zurueck - UpdateReminderDto lehnt null ab (400 statt 500) - keine Mails an deaktivierte Benutzer - Spaeter erinnern beschriftet heute/morgen nach dem berechneten Zeitpunkt - Bearbeiten schickt dueAt nur bei geaenderter Zeit Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
94 lines
3.5 KiB
TypeScript
94 lines
3.5 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
defaultNewReminderInputs,
|
|
isoToLocalInputs,
|
|
isSameLocalDay,
|
|
localInputsToIso,
|
|
snoozeTarget,
|
|
} from './reminder-time';
|
|
|
|
// Alle Zeitpunkte in Ortszeit gebildet (`new Date(y, m, d, h, min)`), damit die
|
|
// Tests in jeder Zeitzone dasselbe pruefen.
|
|
const local = (y: number, m: number, d: number, h = 0, min = 0) => new Date(y, m - 1, d, h, min);
|
|
|
|
describe('localInputsToIso / isoToLocalInputs', () => {
|
|
it('laufen im Kreis', () => {
|
|
const iso = localInputsToIso('2026-10-05', '14:30');
|
|
expect(iso).toBe(local(2026, 10, 5, 14, 30).toISOString());
|
|
expect(isoToLocalInputs(iso as string)).toEqual({ date: '2026-10-05', time: '14:30' });
|
|
});
|
|
|
|
it('liefert null bei unvollstaendiger oder ungueltiger Eingabe', () => {
|
|
expect(localInputsToIso('', '14:30')).toBeNull();
|
|
expect(localInputsToIso('2026-10-05', '')).toBeNull();
|
|
expect(localInputsToIso('2026-13-45', '14:30')).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('defaultNewReminderInputs', () => {
|
|
it('ist die naechste volle Stunde', () => {
|
|
expect(defaultNewReminderInputs(local(2026, 9, 29, 13, 20))).toEqual({
|
|
date: '2026-09-29',
|
|
time: '14:00',
|
|
});
|
|
});
|
|
|
|
it('rollt ueber Mitternacht und Monatsende', () => {
|
|
expect(defaultNewReminderInputs(local(2026, 9, 30, 23, 30))).toEqual({
|
|
date: '2026-10-01',
|
|
time: '00:00',
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('snoozeTarget (E-05)', () => {
|
|
const now = local(2026, 9, 29, 14, 5);
|
|
const original = local(2026, 9, 29, 14, 0);
|
|
|
|
it('10m und 1h zaehlen ab jetzt, nicht ab der alten Faelligkeit', () => {
|
|
expect(snoozeTarget('10m', original, now).getTime()).toBe(now.getTime() + 10 * 60_000);
|
|
expect(snoozeTarget('1h', original, now).getTime()).toBe(now.getTime() + 3600_000);
|
|
});
|
|
|
|
it('morgen = urspruengliche Ortszeit am naechsten Tag', () => {
|
|
expect(snoozeTarget('tomorrow', original, now).getTime()).toBe(
|
|
local(2026, 9, 30, 14, 0).getTime(),
|
|
);
|
|
});
|
|
|
|
it('morgen ueber das Monatsende', () => {
|
|
const n = local(2026, 9, 30, 15, 0);
|
|
expect(snoozeTarget('tomorrow', local(2026, 9, 30, 14, 0), n).getTime()).toBe(
|
|
local(2026, 10, 1, 14, 0).getTime(),
|
|
);
|
|
});
|
|
|
|
it('eine tagelang ueberfaellige Erinnerung landet beim naechsten kuenftigen Vorkommen', () => {
|
|
const old = local(2026, 9, 25, 8, 15);
|
|
const target = snoozeTarget('tomorrow', old, now);
|
|
expect(target.getTime()).toBeGreaterThan(now.getTime());
|
|
expect(target.getTime()).toBe(local(2026, 9, 30, 8, 15).getTime());
|
|
});
|
|
});
|
|
|
|
describe('snoozeTarget kurz nach Mitternacht / isSameLocalDay', () => {
|
|
it('faellig gestern 23:50, verschoben heute 00:10 -> heute 23:50 (heute, nicht morgen)', () => {
|
|
const n = local(2026, 9, 30, 0, 10);
|
|
const target = snoozeTarget('tomorrow', local(2026, 9, 29, 23, 50), n);
|
|
expect(target.getTime()).toBe(local(2026, 9, 30, 23, 50).getTime());
|
|
expect(isSameLocalDay(target, n)).toBe(true);
|
|
});
|
|
|
|
it('der Normalfall liegt am naechsten Tag', () => {
|
|
const n = local(2026, 9, 29, 14, 5);
|
|
const target = snoozeTarget('tomorrow', local(2026, 9, 29, 14, 0), n);
|
|
expect(isSameLocalDay(target, n)).toBe(false);
|
|
});
|
|
|
|
it('isSameLocalDay vergleicht den Kalendertag in Ortszeit', () => {
|
|
expect(isSameLocalDay(local(2026, 9, 30, 0, 0), local(2026, 9, 30, 23, 59))).toBe(true);
|
|
expect(isSameLocalDay(local(2026, 9, 30, 23, 59), local(2026, 10, 1, 0, 0))).toBe(false);
|
|
expect(isSameLocalDay(local(2026, 9, 30), local(2025, 9, 30))).toBe(false);
|
|
});
|
|
});
|