Gästetexte des Terminplaners: Fassung 2026-10-05, Erinnerungs- und Abo-Ende-Satz, Archiv je Fassung

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-05 04:01:49 +00:00
1 parent 1a91a331b4
commit c1266fcce7
11 files changed
+313 -33

No files matched your search

+34 -2
View File
@@ -22,7 +22,7 @@ const aw = await startAppwriteMock({
useTestEnv({ appwriteUrl: aw.url, stripeUrl: 'http://127.0.0.1:1' })
const { config } = await import('../server/config.js')
const { deleteDocument } = await import('../server/services/appwriteAdmin.js')
const { deleteDocument, updateDocument } = await import('../server/services/appwriteAdmin.js')
const { setMailTransportForTests } = await import('../server/services/mailer.js')
const { startTestApp, send } = await import('./support/testApp.js')
const { kundenansichtCookie } = await import('./support/fixtures.js')
@@ -32,7 +32,7 @@ const { resetOutboxForTests, warteAufVersand } = await import('../server/service
const { buchungsNummer, formToken, pruefeFormToken, verwaltungsToken } = await import('../server/services/termine/token.js')
const { speichereEinstellung, resetKontextForTests } = await import('../server/services/termine/kontext.js')
const { resetTermineLimitsForTests, darfHaltung } = await import('../server/services/termine/limits.js')
const { ZUSTIMMUNG_STORNO, ZUSTIMMUNG_ERINNERUNG, ZUSTIMMUNG_VORZEITIG, GESUNDHEIT_HINWEIS, formularHinweis, widerrufsbelehrung } = await import(
const { RECHTSTEXTE_VERSION, ZUSTIMMUNG_STORNO, ZUSTIMMUNG_ERINNERUNG, ZUSTIMMUNG_VORZEITIG, GESUNDHEIT_HINWEIS, formularHinweis, widerrufsbelehrung } = await import(
'../server/services/termine/rechtstexte.js'
)
const { halte } = await import('../server/services/termine/ablauf.js')
@@ -274,6 +274,8 @@ test('config: Betriebsdaten, Leistungen, Regeln, Texte und Formular-Token; keine
gesundheit: GESUNDHEIT_HINWEIS,
widerrufsbelehrung: widerrufsbelehrung(ctx.einstellung.betrieb),
})
// Haken Erinnerung: Wortlaut der Fassung mit dem Widerrufssatz (Art. 7 Abs. 3 DSGVO), wörtlich in der öffentlichen Konfiguration
assert.equal(c.texte.erinnerung, 'Ich möchte 24 Stunden vor dem Termin eine Erinnerung per E-Mail erhalten. Diese Einwilligung kann ich jederzeit widerrufen.')
assert.equal(pruefeFormToken(SITE_KEY, c.formToken, plus(JETZT, 10000)), 'ok')
assert.equal(pruefeFormToken('bcdefghijklmnopq', c.formToken, plus(JETZT, 10000)), 'ungueltig', 'das Token gilt nur fuer diesen siteKey')
@@ -564,6 +566,36 @@ test('Buchung: 201 mit maskierter Adresse und Haltezeit; Buchung gehalten, Mail
assert.ok(!JSON.stringify(res.body).includes(b.$id))
})
test('nachweis_fassung: eine neue Buchung trägt die aktuelle Fassung der Gästetexte, eine Altbuchung behält 2026-10-02 (der Nachweis wird nie umgeschrieben)', async () => {
await speichere()
const { id: neu, verwaltung } = await gebucht({ erinnerung: true, zustimmungen: { storno: true, vorzeitig: false } })
const nachweisNeu = JSON.parse(aw.docs('termineBookings').get(neu).nachweis)
assert.equal(nachweisNeu.fassung, RECHTSTEXTE_VERSION)
assert.notEqual(nachweisNeu.fassung, '2026-10-02')
assert.equal(nachweisNeu.erinnerung.hash.length, 64)
// Altbuchung: Nachweis der Fassung 2026-10-02; Bestätigen, Verschieben und Absagen schreiben den Nachweis nicht um
const alt = await buchen({ email: 'alt@example.com', zeit: '11:00', ressource: R1 })
assert.equal(alt.status, 201)
await warteAufVersand()
const buchungAlt = buchungen().find((b) => b.gastEmail === 'alt@example.com')
const nachweisAlt = JSON.stringify({ ...JSON.parse(buchungAlt.nachweis), fassung: '2026-10-02' })
await updateDocument('termineBookings', buchungAlt.$id, { nachweis: nachweisAlt })
const vToken = tokenAusMail(mailsAn('alt@example.com')[0], 'v')
assert.equal((await tokenAnruf('bestaetigen', { token: vToken })).status, 200)
await warteAufVersand()
const mToken = tokenAusMail(mailsAn('alt@example.com').find((m) => /#m=/.test(m.text)), 'm')
assert.equal((await tokenAnruf('verschieben', { token: mToken, tag: TAG_FERN, zeit: '11:30' })).status, 200)
assert.equal((await tokenAnruf('absagen', { token: mToken })).status, 200)
const danach = aw.docs('termineBookings').get(buchungAlt.$id)
assert.equal(danach.status, 'abgesagt')
assert.equal(danach.nachweis, nachweisAlt, 'der Nachweis der Altbuchung bleibt byte-gleich')
assert.equal(JSON.parse(danach.nachweis).fassung, '2026-10-02')
// die neue Buchung ist davon unberührt
assert.equal(JSON.parse(aw.docs('termineBookings').get(neu).nachweis).fassung, RECHTSTEXTE_VERSION)
assert.ok(verwaltung)
})
test('zu viele offene Termine: dieselbe 201-Antwort, keine neue Buchung, statt der Bestaetigung geht G01 "zu viele"', async () => {
await speichere()
// drei bestaetigte Termine belegen die drei offenen Plaetze; die Kappe der Adresse (3 Mails je Stunde) ist damit ausgeschoepft,