Neue Vorlage K17 im Stil von K16 mit Nachricht, Absender und Link auf den Portal-Chat. Hoechstens eine Mail je Kunde im Zeitfenster CHAT_NOTIFY_THROTTLE_MIN (15 Min.), ohne BCC ans Team, nicht ohne E-Mail-Adresse oder Portalzugang. Das Admin-Panel zeigt unter dem Kundennamen, ob der Hinweis rausging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
3.0 KiB
JavaScript
55 lines
3.0 KiB
JavaScript
import { test, before, beforeEach } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { mailSink } from './support/mailSink.js'
|
|
|
|
// K17: Hinweis an den Kunden, wenn das Team im Portal-Chat schreibt
|
|
let sendCustomerChatNotice, resetChatNoticeThrottleForTests, setMailTransportForTests
|
|
let sink
|
|
|
|
const customer = (extra = {}) => ({ $id: 'c1', name: 'Emma Schatz', email: 'emma@example.com', portalAccessEnabled: true, ...extra })
|
|
|
|
before(async () => {
|
|
Object.assign(process.env, { APPWRITE_ENDPOINT: 'http://127.0.0.1:9/v1', SMTP_HOST: '', CHAT_NOTIFY_EMAILS: 'team@webklar.invalid', PORTAL_PUBLIC_URL: 'https://project.webklar.com' })
|
|
;({ sendCustomerChatNotice, resetChatNoticeThrottleForTests, setMailTransportForTests } = await import('../server/services/mailer.js'))
|
|
})
|
|
|
|
beforeEach(() => {
|
|
sink = mailSink()
|
|
setMailTransportForTests(sink)
|
|
resetChatNoticeThrottleForTests()
|
|
})
|
|
|
|
test('Kunde bekommt K17 mit Nachricht und Portal-Link, ohne BCC ans Team', async () => {
|
|
const result = await sendCustomerChatNotice(customer(), { sender: 'Kenso Grimm', text: 'Hallo <Emma>\nZeile 2' })
|
|
assert.deepEqual(result, { sent: true, to: 'emma@example.com' })
|
|
assert.equal(sink.sent.length, 1)
|
|
const mail = sink.sent[0]
|
|
assert.deepEqual(mail.to.map((t) => t.address), ['emma@example.com'])
|
|
assert.ok(!mail.bcc, "keine Kopie ans Team")
|
|
assert.equal(mail.subject, 'Neue Nachricht von WEBklar')
|
|
assert.match(mail.html, /Hallo Emma Schatz,<br>Kenso Grimm hat Dir/)
|
|
assert.match(mail.html, /Hallo <Emma><br>Zeile 2/)
|
|
assert.match(mail.html, /href="https:\/\/project\.webklar\.com\/dashboard\.html#chat"/)
|
|
assert.match(mail.text, /Hallo <Emma>\nZeile 2/)
|
|
})
|
|
|
|
test('höchstens eine Mail je Kunde im Zeitfenster, andere Kunden unabhängig', async () => {
|
|
assert.equal((await sendCustomerChatNotice(customer(), { sender: 'A', text: 'eins' })).sent, true)
|
|
assert.deepEqual(await sendCustomerChatNotice(customer(), { sender: 'A', text: 'zwei' }), { sent: false, reason: 'throttled', to: 'emma@example.com' })
|
|
assert.equal((await sendCustomerChatNotice(customer({ $id: 'c2', email: 'b@example.com' }), { sender: 'A', text: 'x' })).sent, true)
|
|
assert.equal(sink.sent.length, 2)
|
|
})
|
|
|
|
test('ohne E-Mail oder Portalzugang keine Mail', async () => {
|
|
assert.deepEqual(await sendCustomerChatNotice(customer({ email: '' }), { text: 'x' }), { sent: false, reason: 'keine E-Mail-Adresse' })
|
|
assert.deepEqual(await sendCustomerChatNotice(customer({ portalAccessEnabled: false }), { text: 'x' }), { sent: false, reason: 'kein Portalzugang' })
|
|
assert.equal(sink.sent.length, 0)
|
|
})
|
|
|
|
test('Versandfehler: Nachricht bleibt, nächster Versuch ist nicht gesperrt', async () => {
|
|
setMailTransportForTests({ sendMail: async () => { throw new Error('SMTP weg') } })
|
|
assert.deepEqual(await sendCustomerChatNotice(customer(), { text: 'x' }), { sent: false, reason: 'SMTP weg', to: 'emma@example.com' })
|
|
setMailTransportForTests(sink)
|
|
assert.equal((await sendCustomerChatNotice(customer(), { text: 'y' })).sent, true)
|
|
})
|