import test from 'node:test' import assert from 'node:assert/strict' import { loadModule } from './load.mjs' const { stundenkontoAnsicht, einrichtungText } = await loadModule('src/lib/stundenkontoView.js') test('Vorschuss ohne Guthaben (Beispiel der Spec: 2,5 Stunden)', () => { assert.deepEqual(stundenkontoAnsicht({ produkt: 'wartung', ledger: { balanceMinutes: 0, vorschussMinutes: 150, overageMinutes: 30, nextExpiry: null } }), { art: 'konto', hinweis: '', eintraege: [ { key: 'guthaben', label: 'Guthaben', wert: '0 min', sub: '', ton: '' }, { key: 'vorschuss', label: 'Vorschuss (Einrichtung)', wert: '2 h 30 min', sub: 'wird mit den nächsten Gutschriften verrechnet', ton: 'warn' }, { key: 'mehraufwand', label: 'Mehraufwand', wert: '30 min', sub: '', ton: 'warn' }, ] }) }) test('Guthaben mit Verfall; Vorschuss und Mehraufwand fehlen bei 0', () => { const a = stundenkontoAnsicht({ produkt: 'wartung', ledger: { balanceMinutes: 240, vorschussMinutes: 0, overageMinutes: 0, nextExpiry: { minutes: 60, at: '2027-08-01T12:00:00.000Z' } } }) assert.deepEqual(a.eintraege.map((e) => [e.key, e.wert, e.sub]), [['guthaben', '4 h', ''], ['verfall', '1 h', 'am 01.08.2027']]) }) test('Hosting, kein Abo, unbrauchbare Antworten und Minuten', () => { assert.deepEqual(stundenkontoAnsicht({ produkt: 'hosting', ledger: null }), { art: 'hosting', hinweis: 'Hosting-Abo: kein Stundenkonto.', eintraege: [] }) assert.deepEqual(stundenkontoAnsicht({ produkt: null, ledger: null }), { art: 'keins', hinweis: 'Kein Abo: kein Stundenkonto.', eintraege: [] }) for (const x of [null, undefined, 'x', 5, []]) assert.equal(stundenkontoAnsicht(x), null) const k = stundenkontoAnsicht({ produkt: 'wartung', ledger: { balanceMinutes: 85, vorschussMinutes: -5, overageMinutes: 'abc', nextExpiry: { minutes: 0, at: 'kaputt' } } }) assert.deepEqual(k.eintraege.map((e) => [e.key, e.wert]), [['guthaben', '1 h 25 min']]) }) test('Vorschuss bei beendetem Abo (active false): verfällt, wird nicht berechnet; sonst wie bisher', () => { const ledger = { balanceMinutes: 0, vorschussMinutes: 90, overageMinutes: 30, nextExpiry: null } const vorschuss = (antwort) => stundenkontoAnsicht(antwort).eintraege.find((e) => e.key === 'vorschuss') assert.deepEqual(vorschuss({ produkt: 'wartung', active: false, ledger }), { key: 'vorschuss', label: 'Vorschuss (Einrichtung)', wert: '1 h 30 min', sub: 'verfällt, wird nicht berechnet', ton: 'warn' }) const verrechnet = 'wird mit den nächsten Gutschriften verrechnet' assert.equal(vorschuss({ produkt: 'wartung', active: true, ledger }).sub, verrechnet) // Feld fehlt (altes Portal) oder ist kein boolean false: Verhalten wie bisher for (const active of [undefined, null, 0, '', 'false', 'nein', [], {}]) assert.equal(vorschuss({ produkt: 'wartung', active, ledger }).sub, verrechnet, String(active)) assert.equal(vorschuss({ produkt: 'wartung', ledger }).sub, verrechnet) }) test('beendetes Abo ändert nur den Satz zum Vorschuss: Guthaben, Mehraufwand und Verfall bleiben, ohne Vorschuss kein Eintrag', () => { const ledger = { balanceMinutes: 60, vorschussMinutes: 90, overageMinutes: 30, nextExpiry: { minutes: 60, at: '2027-08-01T12:00:00.000Z' } } const aktiv = stundenkontoAnsicht({ produkt: 'wartung', active: true, ledger }) const beendet = stundenkontoAnsicht({ produkt: 'wartung', active: false, ledger }) assert.deepEqual(beendet.eintraege.map(({ key, wert, ton }) => [key, wert, ton]), aktiv.eintraege.map(({ key, wert, ton }) => [key, wert, ton])) assert.deepEqual(beendet.eintraege.map((e) => e.sub), ['', 'verfällt, wird nicht berechnet', '', 'am 01.08.2027']) const ohne = stundenkontoAnsicht({ produkt: 'wartung', active: false, ledger: { ...ledger, vorschussMinutes: 0 } }) assert.deepEqual(ohne.eintraege.map((e) => e.key), ['guthaben', 'mehraufwand', 'verfall']) // Hosting und kein Abo: active spielt keine Rolle assert.deepEqual(stundenkontoAnsicht({ produkt: 'hosting', active: false, ledger: null }), { art: 'hosting', hinweis: 'Hosting-Abo: kein Stundenkonto.', eintraege: [] }) assert.deepEqual(stundenkontoAnsicht({ produkt: null, active: false, ledger: null }), { art: 'keins', hinweis: 'Kein Abo: kein Stundenkonto.', eintraege: [] }) }) test('einrichtungText', () => { assert.equal(einrichtungText({ einrichtungAbrechnung: 'abo' }), 'Einrichtung aus dem Abo: Die Arbeitszeit geht aufs Stundenkonto des Kunden, auch wenn das Guthaben nicht reicht.') assert.equal(einrichtungText({ einrichtungAbrechnung: 'projekt' }), 'Einrichtung im Projekt enthalten: Die Arbeitszeit zählt nicht aufs Abo-Stundenkonto.') assert.equal(einrichtungText({}), '') })