Files
Webklar-Kundenbereich/test/unterkunftRechnungen.test.js
T

80 lines
4.0 KiB
JavaScript

import { test, after, beforeEach } from 'node:test'
import assert from 'node:assert/strict'
import { startAppwriteMock } from './support/appwriteMock.js'
import { useTestEnv } from './support/testEnv.js'
import { schemaKeys } from './support/schema.js'
// Buchungskalender Task 4: Rechnungsnummern (rechnungen.js) und Token (token.js)
const NAMEN = ['ukUnterkuenfte', 'ukPreise', 'ukSperren', 'ukAnfragen', 'ukRechnungen', 'ukEinstellungen']
const aw = await startAppwriteMock({ schema: Object.fromEntries(NAMEN.map((n) => [n, schemaKeys(n)])) })
useTestEnv({ appwriteUrl: aw.url, stripeUrl: 'http://127.0.0.1:1/v1' })
const { deleteDocument } = await import('../server/services/appwriteAdmin.js')
const re = await import('../server/services/unterkunft/rechnungen.js')
const tk = await import('../server/services/unterkunft/token.js')
const sp = await import('../server/services/unterkunft/speicher.js')
after(() => aw.close())
const NOW = new Date('2026-11-01T12:00:00Z')
beforeEach(async () => {
for (const c of NAMEN) for (const id of aw.docs(c).keys()) await deleteDocument(c, id)
})
test('Nummern laufen hoch', async () => {
assert.equal(await re.naechsteNummer('f1', NOW), 'RE-2026-0001')
assert.equal(await re.naechsteNummer('f1', NOW), 'RE-2026-0002')
assert.equal(await re.naechsteNummer('f2', NOW), 'RE-2026-0001')
})
test('10 parallele Nummern: verschieden und lueckenlos', async () => {
const nr = await Promise.all(Array.from({ length: 10 }, () => re.naechsteNummer('f1', NOW)))
assert.deepEqual([...nr].sort(), Array.from({ length: 10 }, (_, i) => `RE-2026-${String(i + 1).padStart(4, '0')}`))
})
test('Jahreswechsel nach Berliner Kalenderjahr', async () => {
assert.equal(await re.naechsteNummer('f1', new Date('2026-12-31T22:30:00Z')), 'RE-2026-0001')
assert.equal(await re.naechsteNummer('f1', new Date('2026-12-31T23:30:00Z')), 'RE-2027-0001')
assert.equal(await re.naechsteNummer('f1', new Date('2027-01-01T00:30:00+01:00')), 'RE-2027-0002')
})
test('Praefix aus den Einstellungen', async () => {
await sp.speichereEinstellungen('f1', { rechnungsPraefix: 'DH' })
assert.equal(await re.naechsteNummer('f1', NOW), 'DH-2026-0001')
})
test('stelleAus storno negiert Posten und Summen, traegt bezugNummer', async () => {
const anfrage = {
$id: 'a1', unterkunftId: 'u1', nummer: 'A-ABCD', von: '2026-11-10', bis: '2026-11-12', personen: 2, zahlart: 'vorort',
rechnungsadresse: { name: 'Gast' },
posten: [{ text: 'Nacht', menge: 2, einzelCent: 10000, ustProzent: 7 }],
summen: { bruttoCent: 20000, nettoCent: 18692, ust: [{ satz: 7, nettoCent: 18692, steuerCent: 1308 }] },
}
const ctx = { featureId: 'f1', einstellungen: { firma: 'Haus GmbH', iban: 'DE00' } }
const r = await re.stelleAus(ctx, anfrage, { art: 'rechnung', now: NOW })
assert.equal(r.nummer, 'RE-2026-0001')
assert.equal(r.inhalt.aussteller.firma, 'Haus GmbH')
assert.equal(r.inhalt.naechte, 2)
const s = await re.stelleAus(ctx, anfrage, { art: 'storno', bezugNummer: r.nummer, now: NOW })
assert.equal(s.nummer, 'RE-2026-0002')
assert.equal(s.art, 'storno')
assert.equal(s.inhalt.posten[0].einzelCent, -10000)
assert.equal(s.inhalt.summen.bruttoCent, -20000)
assert.equal(s.inhalt.summen.ust[0].steuerCent, -1308)
assert.equal(s.inhalt.bezugNummer, 'RE-2026-0001')
assert.equal((await re.listeRechnungen('f1')).length, 2)
assert.equal((await re.ladeRechnung(s.$id)).nummer, 'RE-2026-0002')
})
test('Token: Hash passt nur zum Token; Formtoken', () => {
const { token, hash } = tk.neuesToken()
assert.equal(tk.tokenPasst(hash, token), true)
assert.equal(tk.tokenPasst(hash, token + 'x'), false)
assert.equal(tk.tokenPasst('', token), false)
const t = tk.formToken('abc', new Date(0 + 1e12))
assert.equal(tk.pruefeFormToken('abc', t, new Date(1e12 + 10000)), 'ok')
assert.equal(tk.pruefeFormToken('abc', t, new Date(1e12 + 100)), 'zu_schnell')
assert.equal(tk.pruefeFormToken('abd', t, new Date(1e12 + 10000)), 'ungueltig')
assert.equal(tk.pruefeFormToken('abc', t, new Date(1e12 + 3 * 3600e3)), 'abgelaufen')
assert.match(tk.ipHashVon('1.2.3.4'), /^[0-9a-f]{16}$/)
})