import { test, after } from 'node:test' import assert from 'node:assert/strict' import { startAppwriteMock } from './support/appwriteMock.js' import { startFakeStripe } from './support/fakeStripe.js' import { useTestEnv } from './support/testEnv.js' import { schemaKeys } from './support/schema.js' // Kundenart im Zustimmungsnachweis (V4): nur geschrieben, wenn uebergeben; ungueltig ist 400 ohne Schreibzugriff const schema = { featureConsents: schemaKeys('featureConsents') } // bleibt aenderbar wie in featureSetup.test.js const aw = await startAppwriteMock({ schema }) const st = await startFakeStripe() after(() => Promise.all([aw.close(), st.close()])) useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url }) const reg = await import('../server/services/featureRegistry.js') const { speichereZustimmung, speichereNachweisAusAnfrage } = await import('../server/services/featureConsents.js') const base = { customerId: 'c1', projectId: 'p1', featureKey: 'termine', stripeSessionId: '', fassungen: { zustimmung: 'x' }, texte: [{ id: 'knopf', text: 'Einschalten', haken: false }], ip: '203.0.113.9', userAgent: 'UA/1', konto: 'k', at: '2026-10-17T08:00:00.000Z' } test('kundenart wird gespeichert; ohne Angabe fehlt der Schlüssel, auch bei altem Schema', async () => { assert.equal((await speichereZustimmung({ ...base, kundenart: 'privat' })).kundenart, 'privat') assert.equal((await speichereZustimmung({ ...base, kundenart: 'unternehmen' })).kundenart, 'unternehmen') schema.featureConsents = schemaKeys('featureConsents').filter((k) => k !== 'kundenart') // Setup-Skript noch nicht gelaufen assert.equal(Object.hasOwn(await speichereZustimmung(base), 'kundenart'), false) await assert.rejects(() => speichereZustimmung({ ...base, kundenart: 'privat' }), /Unknown attribute/) schema.featureConsents = schemaKeys('featureConsents') }) test('ungültige Kundenart: 400, nichts geschrieben', async () => { const vorher = aw.docs('featureConsents').size for (const kundenart of ['firma', '', 'Privat', 3, null]) { await assert.rejects(() => speichereZustimmung({ ...base, kundenart }), (e) => e.status === 400 && /Kundenart ungültig/.test(e.message), String(kundenart)) } assert.equal(aw.docs('featureConsents').size, vorher) }) test('Nachweis aus der Anfrage im Abo-Modell: Zeile, Hinweis, optional Häkchen, Knopf; Fassungen ohne widerruf', async () => { const req = { ip: '203.0.113.9', get: (h) => (h === 'user-agent' ? 'UA/1' : ''), session: { name: 'Kunde Eins', email: 'k@example.invalid' } } const feature = reg.featureConfig('termine') await speichereNachweisAusAnfrage(req, { feature: reg.aboweg(feature), customerId: 'c1', projectId: 'p1', klickAt: '2026-10-17T08:00:00.000Z', kundenart: 'unternehmen' }) await speichereNachweisAusAnfrage(req, { feature: reg.aboweg(feature, { beginn: true }), customerId: 'c1', projectId: 'p2', klickAt: '2026-10-17T08:00:00.000Z', kundenart: 'privat' }) const [a, b] = [...aw.docs('featureConsents').values()].filter((d) => d.featureKey === 'termine' && d.projectId.startsWith('p')).slice(-2) assert.deepEqual(JSON.parse(a.texte).map((t) => t.id), ['einschalten-zeile', 'hinweis', 'knopf']) // termine trägt den Hinweis (Pflichten der alten Häkchen) assert.equal(JSON.parse(a.texte)[1].text, reg.consentAbo('termine').items[1].text) assert.deepEqual(JSON.parse(b.texte).map((t) => [t.id, t.haken]), [['einschalten-zeile', false], ['hinweis', false], ['beginn', true], ['knopf', false]]) assert.deepEqual(Object.keys(JSON.parse(a.fassungen)).sort(), ['avv', 'leistungsbeschreibung', 'zustimmung']) assert.deepEqual([a.kundenart, b.kundenart, a.konto, a.stripeSessionId], ['unternehmen', 'privat', 'Kunde Eins ', '']) }) test('Nachweis aus der Anfrage ohne kundenart: Schlüssel fehlt (alter Weg bleibt)', async () => { const req = { ip: '203.0.113.9', get: () => '', session: { name: 'Kunde Eins', email: 'k@example.invalid' } } await speichereNachweisAusAnfrage(req, { feature: reg.featureConfig('news'), customerId: 'c1', projectId: 'p9', klickAt: '2026-10-17T08:00:00.000Z' }) const doc = [...aw.docs('featureConsents').values()].find((d) => d.projectId === 'p9') assert.equal(Object.hasOwn(doc, 'kundenart'), false) })