From dd0bef52e8cb8e3d2a861c6cfc5c49838b1425ef Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 5 Oct 2026 14:45:03 +0000 Subject: [PATCH] Planboard: Tests halten Datums- und Terminlogik fest (Altwerte, Stornierte, ohne Uhrzeit) Co-Authored-By: Claude Sonnet 5.5 --- tests/unit/planboard.test.mjs | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/unit/planboard.test.mjs diff --git a/tests/unit/planboard.test.mjs b/tests/unit/planboard.test.mjs new file mode 100644 index 0000000..62738ca --- /dev/null +++ b/tests/unit/planboard.test.mjs @@ -0,0 +1,55 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { loadModule } from './load.mjs' + +const { parseGermanDate, formatTime, dayKey, groupAppointmentsByDay, countInRange } = await loadModule('src/lib/planboard.js') + +test('parseGermanDate: ein- und zweistellig, Altwerte ergeben null', () => { + assert.equal(parseGermanDate('2.5.2026').getTime(), new Date(2026, 4, 2).getTime()) + assert.equal(parseGermanDate(' 07.10.2026 ').getTime(), new Date(2026, 9, 7).getTime()) + for (const v of ['31.02.2026', '0.1.2026', '2026-10-07T09:00:00.000Z', '2026-10-07', '7.10.26', '', undefined, null, 'morgen']) { + assert.equal(parseGermanDate(v), null, String(v)) + } +}) + +test('formatTime: hhmm und hh:mm, ungültige Werte ergeben leer', () => { + for (const [v, out] of [['0900', '09:00'], ['900', '09:00'], ['9:00', '09:00'], ['09:30', '09:30'], ['2359', '23:59']]) { + assert.equal(formatTime(v), out, v) + } + for (const v of ['2400', '1260', '9', 'abc', '', undefined]) assert.equal(formatTime(v), '', String(v)) + assert.equal(dayKey(new Date(2026, 0, 5)), '2026-01-05') +}) + +const employees = [{ userId: 'u1', displayName: 'Kenso Grimm', shortcode: 'KNSO' }] +const workorders = [ + { $id: 'a', woid: '1', startDate: '7.10.2026', startTime: '1400', endTime: '1500', topic: 'Spät', type: 'Webpage', status: 'Open', customerName: 'Alpha', assignedTo: 'u1' }, + { $id: 'b', woid: '2', startDate: '07.10.2026', startTime: '', topic: 'Ohne Uhrzeit', type: 'Akquise', status: 'Open', assignedName: 'Ehemalige' }, + { $id: 'c', woid: '3', startDate: '7.10.2026', startTime: '0830', topic: 'Früh', type: 'Webpage', status: 'Cancelled' }, + { $id: 'd', startDate: '8.10.2026', startTime: '1000', title: 'Nur Titel' }, + { $id: 'h', startDate: '9.10.2026' }, + { $id: 'e', woid: '5', startDate: '31.02.2026', startTime: '1000', topic: 'Ungültig' }, + { $id: 'f', woid: '6', startDate: '2026-10-07T09:00:00.000Z', topic: 'ISO' }, + { $id: 'g', woid: '7', startDate: '', topic: 'Leer' }, +] + +test('groupAppointmentsByDay: nach Uhrzeit, ohne Uhrzeit am Ende, Stornierte bleiben, Altwerte fallen weg', () => { + const byDay = groupAppointmentsByDay(workorders, employees) + assert.deepEqual(Object.keys(byDay).sort(), ['2026-10-07', '2026-10-08', '2026-10-09']) + assert.deepEqual(byDay['2026-10-07'].map((a) => a.id), ['c', 'a', 'b']) + assert.equal(byDay['2026-10-07'][0].status, 'Cancelled') + assert.equal(byDay['2026-10-07'][1].employeeShort, 'KNSO') + assert.equal(byDay['2026-10-07'][1].employeeName, 'Kenso Grimm') + assert.equal(byDay['2026-10-07'][2].employeeName, 'Ehemalige') + assert.equal(byDay['2026-10-07'][2].employeeShort, '') + assert.equal(byDay['2026-10-08'][0].woid, '') + assert.equal(byDay['2026-10-08'][0].topic, 'Nur Titel') + assert.equal(byDay['2026-10-09'][0].topic, 'Ohne Betreff') +}) + +test('countInRange: zählt nur die genannten Tage', () => { + const byDay = groupAppointmentsByDay(workorders, employees) + const week = (day) => Array.from({ length: 7 }, (_, i) => new Date(2026, 9, day + i)) + assert.equal(countInRange(byDay, week(5)), 5) + assert.equal(countInRange(byDay, week(12)), 0) + assert.equal(countInRange(byDay), 0) +})