import test from 'node:test'; import assert from 'node:assert/strict'; import { chunks, matchUsers, ursache } from '../src/lib/hrworksSync.js'; import { ABSENCE_STATES, SICK_STATES } from '../src/lib/hrworks.js'; test('ein Feiertag gewinnt gegen Urlaub am selben Tag', () => { assert.deepEqual(ursache({ holiday: true, absences: ['30_25'], sick_leaves: [] }), { art: 'holiday', ref: null }); assert.deepEqual(ursache({ holiday: false, absences: ['30_25'], sick_leaves: [] }), { art: 'absence', ref: '30_25' }); // Krankheit vor Urlaub: wer im Urlaub krank wird, ist krank. assert.deepEqual(ursache({ holiday: false, absences: ['30_25'], sick_leaves: ['31_9'] }), { art: 'sick', ref: '31_9' }); assert.equal(ursache({ holiday: false, absences: [], sick_leaves: [] }), null); }); test('Zuordnung: Mailadresse zuerst, dann Name', () => { const users = [ { id: 1, name: 'Kai Schwickert', email: 'kai.schwickert@icon-experts.de' }, { id: 2, name: 'Nico Necknig', email: 'nico.necknig@perinco.de' }, { id: 3, name: 'Renè Kleinau', email: 'rene.kleinau@perinco.de' }, ]; const persons = [ // andere Domain in HRworks - greift ueber den Namen { person_id: 'KaiS', name: 'Kai Schwickert', email: 'kai.schwickert@perinco.de' }, // private Adresse in HRworks - greift ueber den Namen { person_id: 'NicoN', name: 'Nico Necknig', email: 'nico.necknig@web.de' }, // Akzent unterschiedlich geschrieben { person_id: 'ReneK', name: 'Rene Kleinau', email: 'andere@perinco.de' }, { person_id: 'ServiceA', name: 'Service Account', email: 'sa.hrworks@perinco.de' }, ]; const { matched, unmatched } = matchUsers(persons, users); assert.equal(matched.get('KaiS').id, 1); assert.equal(matched.get('NicoN').id, 2); assert.equal(matched.get('ReneK').id, 3); assert.deepEqual(unmatched.map((u) => u.person_id), ['ServiceA']); }); test('doppelte Namen ergeben keinen Treffer', () => { const users = [ { id: 5, name: 'Luisa Sauerwald', email: 'lusia.sauerwald@perinco.de' }, { id: 23, name: 'Luisa Sauerwald', email: 'luisa.sauerwald@perinco.de' }, ]; // Mail passt: eindeutig. let r = matchUsers([{ person_id: 'LuisaS', name: 'Luisa Sauerwald', email: 'luisa.sauerwald@perinco.de' }], users); assert.equal(r.matched.get('LuisaS').id, 23); // Mail passt nicht: der Name ist zweimal da, also lieber melden als raten. r = matchUsers([{ person_id: 'LuisaS', name: 'Luisa Sauerwald', email: 'x@y.de' }], users); assert.equal(r.matched.size, 0); assert.equal(r.unmatched.length, 1); }); test('Zeitraum wird in Abschnitte von hoechstens 31 Tagen zerlegt', () => { assert.deepEqual(chunks('2026-09-01', '2026-09-05'), [['2026-09-01', '2026-09-05']]); const lang = chunks('2026-07-23', '2026-09-21'); assert.equal(lang.length, 2); assert.equal(lang[0][0], '2026-07-23'); assert.equal(lang[lang.length - 1][1], '2026-09-21'); for (const [von, bis] of lang) { const tage = (new Date(bis) - new Date(von)) / 86400000 + 1; assert.ok(tage <= 31, `${von}-${bis} hat ${tage} Tage`); } }); test('nur genehmigte Abwesenheiten, bei Krankheit auch offene Bescheinigungen', () => { assert.deepEqual(ABSENCE_STATES, ['validatedOk']); assert.ok(SICK_STATES.includes('certificatePending')); assert.ok(SICK_STATES.includes('reported')); assert.ok(!SICK_STATES.includes('cancelled')); assert.ok(!ABSENCE_STATES.includes('requested')); }); test('Abschnitte mit eigener Groesse (Abwesenheiten: hoechstens ein Jahr)', () => { const teile = chunks('2025-10-01', '2027-11-01', 365); assert.equal(teile.length, 3); for (const [von, bis] of teile) assert.ok((new Date(bis) - new Date(von)) / 86400000 + 1 <= 365); });