Zusatzspeicher: Vorschau im flexiblen Abrechnungsmodus, Aufgaben nach Zeitpunkt, keine stillen Abbrüche

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Fable 5.1 committed 2026-09-29 09:16:07 +00:00
1 parent 188db4b3c1
commit bc20ce0673
9 files changed
+922 -228

No files matched your search

+40 -2
View File
@@ -4,13 +4,16 @@ import { test } from 'node:test'
import { escapeHtml, htmlToText, loadTemplate, renderMail, templateIds } from '../server/services/mailTemplates.js'
const DIR = new URL('../server/mail-templates/', import.meta.url)
// K12, K14 und T12 (Wechsel ins Wartungs-Abo) aus Task 9; K13/T13 und die Endfassung der Texte folgen in Task 12
// K12, K14 und T12 (Wechsel ins Wartungs-Abo) aus Task 9, K13 und T13 (Zusatzspeicher) aus Task 8 (Fix 1);
// die Endfassung der Texte folgt in Task 12
const EXPECTED = [
...Array.from({ length: 11 }, (_, i) => `K${String(i + 1).padStart(2, '0')}`),
'K12',
'K13',
'K14',
...Array.from({ length: 11 }, (_, i) => `T${String(i + 1).padStart(2, '0')}`),
'T12',
'T13',
]
const sampleValues = (tpl) => Object.fromEntries(tpl.placeholders.map((p) => [p, `Wert-${p}`]))
@@ -26,7 +29,8 @@ for (const id of EXPECTED) {
const source = readFileSync(new URL(tpl.file, DIR), 'utf8')
const title = source.match(/<title>([\s\S]*?)<\/title>/)[1]
assert.equal(title, tpl.subject, 'Betreff im Kopf und <title> sind gleich')
assert.equal(id.startsWith('T'), tpl.subject.startsWith('[Abo]') || id === 'T01', 'Team-Hinweise ab T02 mit [Abo]')
// F34: Team-Hinweise tragen [Abo], [Speicher] (Zusatzspeicher-Aufgaben) oder [Datenschutz] (Loeschfristen)
assert.equal(id.startsWith('T'), /^\[(Abo|Speicher|Datenschutz)\]/.test(tpl.subject) || id === 'T01', 'Team-Hinweise ab T02 mit [Abo], [Speicher] oder [Datenschutz]')
const used = new Set([...tpl.body.matchAll(/\{\{(\w+)\}\}/g), ...tpl.subject.matchAll(/\{\{(\w+)\}\}/g)].map((m) => m[1]))
assert.deepEqual([...used].sort(), [...tpl.placeholders].sort(), 'deklarierte = verwendete Platzhalter')
@@ -200,3 +204,37 @@ test('Wechsel-Mails nennen keine feste Frist von 23 Stunden', () => {
assert.doesNotMatch(renderMail(id, sampleValues(tpl), allBlocks(tpl, true)).text, /23 Stunden/, id)
}
})
// Task 8 (Fix 1): K13 (Kunde) und T13 (Team) fuer den Zusatzspeicher, Aufbau wie K12/T12; Endfassung der Texte in Aufgabe 12
test('K13, T13: Betreff, Platzhalter und Blöcke des Zusatzspeichers', () => {
assert.equal(loadTemplate('K13').subject, 'Ihr E-Mail-Zusatzspeicher – Bestätigung')
assert.deepEqual(loadTemplate('K13').placeholders, ['name', 'pakete', 'gesamt_gb', 'monatspreis_zusatz', 'wirksam_ab'])
assert.deepEqual(loadTemplate('K13').blocks, ['plus', 'minus'])
assert.equal(loadTemplate('T13').subject, '[Speicher] {{aktion}}: {{email}}')
for (const p of ['aktion', 'email', 'name', 'stripe_abo_id', 'postfaecher_hinweis', 'neue_groesse_gb', 'pakete', 'faellig']) {
assert.ok(loadTemplate('T13').placeholders.includes(p), p)
}
assert.deepEqual([...loadTemplate('T13').blocks].sort(), ['einrichten', 'nachweis_fehlt', 'periodenende', 'teilweise'])
const values = sampleValues(loadTemplate('K13'))
const plus = renderMail('K13', values, { plus: true })
assert.deepEqual(plus.problems, [])
assert.match(plus.text, /gemäß § 19 UStG ohne Umsatzsteuer/)
assert.match(plus.text, /wird eingerichtet/)
assert.match(plus.text, /14 Tagen widerrufen/)
assert.match(plus.text, /Vertragsunterlagen im Anhang/)
assert.doesNotMatch(plus.text, /ohne anteilige Erstattung/)
const minus = renderMail('K13', values, { minus: true })
assert.match(minus.text, /ohne anteilige Erstattung/)
assert.match(minus.text, /keine neuen E-Mails/)
assert.doesNotMatch(minus.text, /wird eingerichtet|14 Tagen widerrufen|im Anhang/)
const t = loadTemplate('T13')
const teilweise = renderMail('T13', { ...sampleValues(t), pakete: 5 }, { einrichten: true, teilweise: true })
assert.deepEqual(teilweise.problems, [])
assert.match(teilweise.text, /Schritt 2 fehlgeschlagen/)
assert.match(teilweise.text, /von Hand auf 5 setzen/)
assert.match(renderMail('T13', sampleValues(t), { nachweis_fehlt: true }).text, /Nachweis nicht gespeichert/)
assert.match(renderMail('T13', sampleValues(t), { periodenende: true }).text, /Periodenende|zum Wert-faellig/)
assert.doesNotMatch(renderMail('T13', sampleValues(t), {}).text, /Schritt 2 fehlgeschlagen|Nachweis nicht gespeichert/)
})