import { test, after, beforeEach, mock } from 'node:test' import assert from 'node:assert/strict' import { startAppwriteMock } from './support/appwriteMock.js' import { startFakeStripe } from './support/fakeStripe.js' import { schemaKeys } from './support/schema.js' import { useTestEnv } from './support/testEnv.js' import { AUFTRAEGE_DATETIMES } from '../server/services/auftraege/schema.js' const aw = await startAppwriteMock({ schema: { auftraege: schemaKeys('auftraege'), projektRechnungen: schemaKeys('projektRechnungen') }, datetimes: AUFTRAEGE_DATETIMES, defaultLimit: 25, }) const st = await startFakeStripe() useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url }) const { config } = await import('../server/config.js') const { seedRechnungsDaten, legeAuftragAn, leereRechnungsDaten } = await import('./auftraegeRechnungenHilfe.js') const { mapInvoice, createProjectInvoice, rechnungsVorschau, sendInvoiceNow, voidInvoice, deleteDraft, invalidateFinanceCache, resetInvoiceCreateGuardForTests, } = await import('../server/services/finance/stripeFinance.js') const { getProjektRechnung } = await import('../server/services/auftraege/projektRechnungenStore.js') const { getAuftrag } = await import('../server/services/auftraege/auftragStore.js') const { sperreAuftrag } = await import('../server/services/auftraege/konstanten.js') const { withLocks } = await import('../server/services/keyedLock.js') const { berlinDate, formatDe } = await import('../server/services/finance/dates.js') after(() => Promise.all([aw.close(), st.close()])) seedRechnungsDaten(aw) config.auftraege.mode = 'on' beforeEach(async () => { mock.restoreAll() await leereRechnungsDaten(aw, st) invalidateFinanceCache() resetInvoiceCreateGuardForTests() }) const NBSP = String.fromCharCode(160) // geschütztes Leerzeichen U+00A0, wie euroDe es vor € setzt const POSTEN = [{ description: 'Domain', quantity: 1, unitAmountCents: 1200 }] const callsTo = (method, path) => st.calls.filter((c) => c.method === method && (path instanceof RegExp ? path.test(c.path) : c.path === path)) const writes = () => st.calls.filter((c) => c.method !== 'GET') const wirft = (promise, status, message) => assert.rejects(promise, (err) => { assert.equal(err.status, status, `Status ${err.status}: ${err.message}`) assert.equal(err.message, message) return true }) test('mapInvoice: Projektfelder aus den Metadaten, art mit Rückfall abo oder frei', () => { const roh = (over = {}) => ({ id: 'in_1', object: 'invoice', status: 'open', customer: 'cus_1', created: 1_790_000_000, total: 1000, metadata: {}, lines: { object: 'list', data: [] }, ...over }) const felder = (r) => [r.projektId, r.projektName, r.art, r.auftragId, r.auftragNummer] const heute = { today: '2026-10-06' } assert.deepEqual(felder(mapInvoice(roh(), heute)), ['', '', 'frei', '', '']) assert.deepEqual(felder(mapInvoice(roh({ subscription: 'sub_1' }), heute)), ['', '', 'abo', '', '']) const metadata = { projektId: 'p1', projektName: 'Website Wolf', art: 'schluss', auftragId: 'a1', auftragNummer: 'AB-2026-0002' } assert.deepEqual(felder(mapInvoice(roh({ metadata }), heute)), ['p1', 'Website Wolf', 'schluss', 'a1', 'AB-2026-0002']) for (const art of ['quatsch', 'abo', '']) assert.equal(mapInvoice(roh({ metadata: { art } }), heute).art, 'frei', `art "${art}"`) })