import test from 'node:test' import assert from 'node:assert/strict' import { loadModule } from './load.mjs' const { anfangszustand, reduce } = await loadModule('src/lib/rechnungDialogState.js') test('anfangszustand: nichts gewählt, eine leere Position, Zahlungsziel 14', () => { assert.deepEqual(anfangszustand({ projektId: 'p1' }), { projektId: 'p1', art: '', auftragId: '', items: [{ uid: 1, description: '', quantity: '1', price: '' }], zusatz: [], abgewaehlt: [], weitereTickets: [], anzahlung: {}, zeilentexte: {}, zeitraum: '', zeitraumGeaendert: false, days: '14', tageGeaendert: false, memo: '', }) assert.equal(anfangszustand().projektId, null) assert.equal(anfangszustand({ projektId: '' }).projektId, '') }) test('projekt: setzt alles zurück, behält aber Zahlungsziel und Notiz', () => { let s = anfangszustand({ projektId: 'p1' }) s = reduce(s, { type: 'tage', wert: '30' }) s = reduce(s, { type: 'notiz', wert: 'Danke' }) s = reduce(s, { type: 'art', art: 'aufwand' }) s = reduce(s, { type: 'blatt', id: 'b1' }) s = reduce(s, { type: 'zeilentext', schluessel: '2026-10-06', text: 'Neu', original: 'Alt' }) s = reduce(s, { type: 'projekt', projektId: 'p2' }) assert.equal(s.projektId, 'p2') assert.equal(s.art, '') assert.deepEqual(s.abgewaehlt, []) assert.deepEqual(s.zeilentexte, {}) assert.equal(s.days, '30') assert.equal(s.memo, 'Danke') assert.equal(reduce(s, { type: 'projekt', projektId: null }).projektId, null) }) test('art: Positionen für Festbetrag und Zusatzpositionen bleiben getrennt und erhalten', () => { let s = anfangszustand({ projektId: 'p1' }) s = reduce(s, { type: 'position', liste: 'items', uid: 1, feld: 'description', wert: 'Pauschale' }) s = reduce(s, { type: 'position+', liste: 'zusatz' }) s = reduce(s, { type: 'position', liste: 'zusatz', uid: 2, feld: 'price', wert: '12,00' }) s = reduce(s, { type: 'art', art: 'aufwand' }) assert.equal(s.art, 'aufwand') assert.equal(s.items[0].description, 'Pauschale') assert.deepEqual(s.zusatz, [{ uid: 2, description: '', quantity: '1', price: '12,00' }]) // eine unbekannte Liste oder ein unbekanntes Feld ändert nichts assert.equal(reduce(s, { type: 'position', liste: 'x', uid: 1, feld: 'description', wert: 'y' }), s) assert.equal(reduce(s, { type: 'position', liste: 'items', uid: 1, feld: 'uid', wert: 9 }), s) }) test('position+ und position-: Positionen mindestens 1, Zusatzpositionen mindestens 0, höchstens 20', () => { let s = anfangszustand({ projektId: 'p1' }) assert.equal(reduce(s, { type: 'position-', liste: 'items', uid: 1 }), s) s = reduce(s, { type: 'position+', liste: 'zusatz' }) assert.equal(s.zusatz[0].uid, 2) s = reduce(s, { type: 'position-', liste: 'zusatz', uid: 2 }) assert.deepEqual(s.zusatz, []) for (let i = 0; i < 25; i += 1) s = reduce(s, { type: 'position+', liste: 'zusatz' }) assert.equal(s.zusatz.length, 20) }) test('blatt: Abwählen und Wiederanwählen', () => { let s = anfangszustand({ projektId: 'p1' }) s = reduce(s, { type: 'blatt', id: 'b2' }) assert.deepEqual(s.abgewaehlt, ['b2']) s = reduce(s, { type: 'blatt', id: 'b2' }) assert.deepEqual(s.abgewaehlt, []) }) test('ticket+ und ticket-: ein Ticket nur einmal, beim Entfernen verschwindet die Abwahl seiner Blätter', () => { const ticket = { ticketId: 't2', woid: '100140', titel: 'Kontaktformular' } let s = anfangszustand({ projektId: 'p1' }) s = reduce(s, { type: 'ticket+', ticket }) s = reduce(s, { type: 'ticket+', ticket }) assert.deepEqual(s.weitereTickets, [ticket]) s = reduce(s, { type: 'blatt', id: 'w1' }) s = reduce(s, { type: 'blatt', id: 'b9' }) s = reduce(s, { type: 'ticket-', ticketId: 't2', blattIds: ['w1'] }) assert.deepEqual(s.weitereTickets, []) assert.deepEqual(s.abgewaehlt, ['b9']) }) test('zeitraum-vorschlag gilt nur, solange der Nutzer das Feld nicht selbst geändert hat', () => { let s = anfangszustand({ projektId: 'p1' }) s = reduce(s, { type: 'zeitraum-vorschlag', text: '01.10.–20.10.2026' }) assert.deepEqual([s.zeitraum, s.zeitraumGeaendert], ['01.10.–20.10.2026', false]) assert.equal(reduce(s, { type: 'zeitraum-vorschlag', text: '01.10.–20.10.2026' }), s) // gleicher Text: kein neuer Zustand s = reduce(s, { type: 'zeitraum', text: 'Oktober 2026' }) assert.deepEqual([s.zeitraum, s.zeitraumGeaendert], ['Oktober 2026', true]) assert.equal(reduce(s, { type: 'zeitraum-vorschlag', text: '02.10.–21.10.2026' }).zeitraum, 'Oktober 2026') // ein Wechsel der Art verwirft einen Vorschlag, nicht aber die Eingabe des Nutzers const vorschlag = reduce(anfangszustand({ projektId: 'p1' }), { type: 'zeitraum-vorschlag', text: '01.10.–20.10.2026' }) assert.equal(reduce(vorschlag, { type: 'art', art: 'festbetrag' }).zeitraum, '') assert.equal(reduce(s, { type: 'art', art: 'festbetrag' }).zeitraum, 'Oktober 2026') }) test('zeilentext: ein unveränderter oder leerer Text entfernt den Eintrag', () => { let s = anfangszustand({ projektId: 'p1' }) const setze = (text) => reduce(s, { type: 'zeilentext', schluessel: '2026-10-06', text, original: 'Alt' }) s = setze('Neu') assert.deepEqual(s.zeilentexte, { '2026-10-06': 'Neu' }) s = setze('Alt') assert.deepEqual(s.zeilentexte, {}) s = setze('Neu') s = setze(' ') assert.deepEqual(s.zeilentexte, {}) }) test('anzahlung und auftrag: Eingaben ergänzen sich, eine andere AB setzt sie zurück', () => { let s = anfangszustand({ projektId: 'p1' }) s = reduce(s, { type: 'anzahlung', patch: { modus: 'betrag' } }) s = reduce(s, { type: 'anzahlung', patch: { wert: '400,00' } }) assert.deepEqual(s.anzahlung, { modus: 'betrag', wert: '400,00' }) s = reduce(s, { type: 'auftrag', auftragId: 'a2' }) assert.deepEqual([s.auftragId, s.anzahlung], ['a2', {}]) assert.equal(reduce(s, { type: 'gibtsnicht' }), s) }) test('tage-vorschlag: übernimmt das Zahlungsziel der AB, solange der Nutzer es nicht selbst geändert hat', () => { let s = anfangszustand({ projektId: 'p1' }) s = reduce(s, { type: 'tage-vorschlag', wert: '30' }) assert.equal(s.days, '30') assert.equal(s.tageGeaendert, false) assert.equal(reduce(s, { type: 'tage-vorschlag', wert: '30' }), s) // derselbe Wert: nichts zu tun s = reduce(s, { type: 'tage-vorschlag', wert: '14' }) // andere AB gewählt: der Vorschlag folgt assert.equal(s.days, '14') // eine Eingabe des Nutzers wird nie überschrieben, auch nicht nach einem Projektwechsel s = reduce(s, { type: 'tage', wert: '7' }) assert.equal(s.tageGeaendert, true) assert.equal(reduce(s, { type: 'tage-vorschlag', wert: '30' }), s) s = reduce(s, { type: 'projekt', projektId: 'p2' }) assert.equal(s.days, '7') assert.equal(reduce(s, { type: 'tage-vorschlag', wert: '30' }).days, '7') })