38 lines
4.5 KiB
JavaScript
38 lines
4.5 KiB
JavaScript
import assert from 'node:assert/strict'
|
||
import { test } from 'node:test'
|
||
import { loadTemplate, renderMail, templateIds } from '../server/services/mailTemplates.js'
|
||
|
||
// P6 Task 3: Mailvorlagen K38 bis K41 und T24 des Abo-Modells (Kopien von K16 bzw. T19, du-Form, ohne Euro-Zeichen)
|
||
const SOLL = { // [Datei, Betreff, Platzhalter, Blöcke]
|
||
K38: ['K38 Funktion wird eingerichtet.html', 'Deine Funktion wird eingerichtet: {{funktion}}', ['kunde_name', 'projekt', 'funktion', 'funktion_akk', 'einrichtung', 'ticket', 'fassung', 'portal_url'], ['stundenkonto', 'projekt_kosten', 'anhang']],
|
||
K39: ['K39 Funktion beendet.html', 'Deine Funktion wurde beendet: {{funktion}}', ['kunde_name', 'projekt', 'funktion', 'loeschtag', 'portal_url'], ['abo_ende', 'hosting', 'termine', 'offene']],
|
||
K40: ['K40 Zeiten Abo-Ende.html', 'Dein Abo ist beendet – Öffnungszeiten live läuft noch bis {{frist}}', ['kunde_name', 'projekt', 'frist', 'portal_url'], ['abo_ende', 'hosting', 'wechsel_widerrufen']],
|
||
K41: ['K41 Zeiten abgeschaltet Abo.html', 'Öffnungszeiten live ist abgeschaltet', ['kunde_name', 'projekt', 'loeschdatum', 'portal_url'], []],
|
||
K42: ['K42 Webshop-Anfrage Abo.html', 'Deine Webshop-Anfrage für {{projekt}}', ['kunde_name', 'projekt', 'begruendung', 'portal_url'], ['angenommen', 'abgelehnt']],
|
||
K43: ['K43 Anfrage Buchungskalender Abo.html', 'Deine Anfrage zum Buchungskalender für {{projekt}}', ['kunde_name', 'projekt', 'begruendung', 'portal_url'], ['angenommen', 'abgelehnt']],
|
||
T24: ['T24 Funktion eingeschaltet.html', '[Abo] Funktion eingeschaltet: {{funktion}} – {{kunde_name}}', ['kunde_name', 'email', 'projekt', 'funktion', 'woid', 'kontostand', 'woms_url'], ['vorschuss', 'anhang_fehlt']],
|
||
}
|
||
const mail = (id, on) => { const t = loadTemplate(id); return renderMail(id, Object.fromEntries(t.placeholders.map((p) => [p, `W-${p}`])), Object.fromEntries(t.blocks.map((b) => [b, on]))) }
|
||
for (const [id, [file, subject, placeholders, blocks]] of Object.entries(SOLL)) test(`${id}: Datei, Betreff, Platzhalter, Blöcke; rendert ohne Reste; ohne € und ohne Sie-Form (K)`, () => {
|
||
const t = loadTemplate(id); assert.deepEqual([t.file, t.subject, t.placeholders, t.blocks], [file, subject, placeholders, blocks])
|
||
for (const on of [true, false]) { const m = mail(id, on); assert.deepEqual(m.problems, []); assert.doesNotMatch(m.html + m.text, /€/); if (id.startsWith('K')) assert.doesNotMatch(m.text, /\bSie\b|\bIhr/) }
|
||
})
|
||
test('Festtexte', () => {
|
||
assert.match(mail('K38', true).text, /Die Einrichtung geht von deinem Stundenkonto ab, auch wenn das Guthaben noch nicht reicht\. Extrakosten entstehen keine\./)
|
||
assert.match(mail('K38', true).text, /Von deinem Stundenkonto geht nichts ab\. Die Funktion läuft, solange dein Wartungs-Abo läuft\./)
|
||
assert.doesNotMatch(mail('K38', false).text, /Stundenkonto|Wartungs-Abo läuft/)
|
||
assert.match(mail('K39', true).text, /Läuft bis dahin wieder ein passendes Abo, schalten wir W-funktion automatisch und ohne Gebühr wieder ein\./)
|
||
assert.match(mail('K39', true).text, /Bitte informiere deine Gäste selbst\./); assert.doesNotMatch(mail('K39', false).text, /CSV|Offene Bestellungen/)
|
||
assert.match(mail('T24', true).text, /Das Guthaben reicht voraussichtlich nicht \(W-kontostand\)\./); assert.doesNotMatch(mail('T24', false).text, /Vorschuss/)
|
||
})
|
||
test('K42, K43: Zusage ohne Preis und ohne „bestellen“, Absage mit Begründung wie K24 und K34', () => {
|
||
const werte = { kunde_name: 'Erika', projekt: 'Töpferei', begruendung: 'Wir verkaufen keine <Waffen>.', portal_url: 'https://portal.example/dashboard.html#x?projekt=p1' }
|
||
for (const [id, satz, knopf] of [['K42', 'Du kannst den Webshop jetzt im Kundenportal einschalten; danach richten wir ihn ein.', 'Webshop einschalten'], ['K43', 'Du kannst ihn jetzt im Kundenportal einschalten; danach richten wir ihn ein.', 'Zum Kundenportal']]) {
|
||
const zu = renderMail(id, werte, { angenommen: true, abgelehnt: false }); assert.deepEqual(zu.problems, [])
|
||
assert.doesNotMatch(zu.html + zu.text, /€|UStG|bestell|Preis|Waffen/i); assert.ok(zu.text.includes(satz), id); assert.ok(zu.text.includes(knopf), id)
|
||
const ab = renderMail(id, werte, { angenommen: false, abgelehnt: true }); assert.deepEqual(ab.problems, [])
|
||
assert.match(ab.text, /leider/); assert.match(ab.text, /Wir verkaufen keine <Waffen>\./); assert.doesNotMatch(ab.text + ab.html, /€|UStG|bestell/i)
|
||
}
|
||
})
|
||
test('templateIds enthält K38 bis K43 und T24', () => { for (const id of Object.keys(SOLL)) assert.ok(templateIds().includes(id)) })
|