Mails: Produktname statt fest Wartungs-Abo, neue Mails für Wechsel und Zusatzspeicher, UptimeRobot-Hinweis

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Fable 5.1 committed 2026-09-29 10:38:43 +00:00
1 parent 0d2254ca20
commit 19f9c747a2
24 files changed
+407 -100

No files matched your search

+51 -1
View File
@@ -27,9 +27,17 @@ const { recordContractEvent, listContractEvents, eventIdFor } = await import('..
const { deleteDocument } = await import('../server/services/appwriteAdmin.js')
const { withdrawalDeadline } = await import('../server/services/deadlines.js')
const { offerText } = await import('../server/services/offers.js')
const { setMailTransportForTests } = await import('../server/services/mailer.js')
const { mailSink } = await import('./support/mailSink.js')
const app = await startTestApp({ '/api/abo': aboRoutes })
after(() => Promise.all([app.close(), aw.close(), st.close()]))
// F25: Mails landen in einer Senke statt bei SMTP, damit K01 (Anhang je Fassung) und T02 pruefbar sind (Task 12)
const mails = mailSink()
setMailTransportForTests(mails)
after(() => {
setMailTransportForTests(null)
return Promise.all([app.close(), aw.close(), st.close()])
})
seedFixtures(aw)
const DAY_MS = 86400000
@@ -399,6 +407,48 @@ test('Webhook checkout.session.completed: Ereignis abschluss ab Vertragsschluss,
}
})
// Task 12: K01 je Produkt (Katalogname, Preis, Liste „Enthalten“) mit dem PDF der Fassung, der der Kunde zugestimmt
// hat (§ 312f BGB, contractAttachmentFor); T02 nennt das Produkt und die Aufgabe fuer UptimeRobot
test('Webhook checkout.session.completed: K01 je Produkt mit PDF der zugestimmten Fassung, T02 mit UptimeRobot', async () => {
const subH = 'sub_1SD6y2SxAbCdEfGhIjKlMnOs'
st.subscriptions.set(subH, stripeSubscription({ id: subH, customerId: 'c3', productKey: 'hosting' }))
try {
mails.sent.length = 0
const res = await postWebhook(checkoutCompleted(subH))
assert.equal(res.status, 200, JSON.stringify(res.body))
const k01 = mails.sent.find((m) => m.subject.includes('Vertragsbestätigung'))
assert.ok(k01, 'K01 verschickt')
assert.equal(k01.subject, 'Ihr WEBklar Hosting-Abo – Vertragsbestätigung')
assert.deepEqual(k01.attachments.map((a) => [a.filename, a.contentType]), [['WEBklar-Abo-Vertragsunterlagen.pdf', 'application/pdf']])
assert.ok(k01.attachments[0].content.length > 1000, 'PDF-Inhalt angehaengt')
for (const text of ['15,00 € / Monat', 'gemäß § 19 UStG ohne Umsatzsteuer', '1 E-Mail-Postfach', `(Version ${config.abo.termsVersion})`]) {
assert.ok(k01.text.includes(text), `${text}\n---\n${k01.text}`)
}
assert.ok(!k01.text.includes('Stunde Arbeitszeit') && !k01.text.includes('Stundenkontingent'), k01.text)
assert.ok(aw.docs('subscriptions').get(subH).confirmationSentAt)
const t02 = mails.sent.find((m) => m.subject.startsWith('[Abo] Neues'))
assert.ok(t02.subject.startsWith('[Abo] Neues Hosting-Abo: '), t02.subject)
assert.ok(t02.text.includes('Website als Monitor in UptimeRobot anlegen'), t02.text)
} finally {
await cleanupWebhook(subH)
}
// Wartungs-Abo nach Fassung 3 (Altbestand): das Archiv-PDF der Fassung 3, Stunde und beliebig viele Postfaecher
const subW = 'sub_1SD6z3TxAbCdEfGhIjKlMnOt'
st.subscriptions.set(subW, stripeSubscription({ id: subW, customerId: 'c3', productKey: 'wartung', metadata: { termsVersion: '2026-09-25-v3' } }))
try {
mails.sent.length = 0
assert.equal((await postWebhook(checkoutCompleted(subW, { productKey: 'wartung' }))).status, 200)
const k01 = mails.sent.find((m) => m.subject.includes('Vertragsbestätigung'))
assert.equal(k01.subject, 'Ihr WEBklar Wartungs-Abo – Vertragsbestätigung')
assert.deepEqual(k01.attachments.map((a) => a.filename), ['WEBklar-Wartungs-Abo-Vertragsunterlagen.pdf'])
for (const text of ['50,00 € / Monat', 'beliebig viele Postfächer', '1 Stunde Arbeitszeit je bezahltem Monat', '(Version 2026-09-25-v3)']) {
assert.ok(k01.text.includes(text), `${text}\n---\n${k01.text}`)
}
} finally {
await cleanupWebhook(subW)
}
})
// Fix 1, Important: ein dauerhafter Fehler beim Nachweis (4xx, z. B. Collection oder Attribut fehlt) darf
// Angebot, T02 und K01 nicht blockieren; ein voruebergehender (5xx, Netz) gibt 500, Stripe wiederholt
test('Webhook: Nachweis dauerhaft nicht speicherbar (400) → 200, Angebot trotzdem aktiviert', async () => {