import { test, after, beforeEach } from 'node:test' import assert from 'node:assert/strict' import os from 'node:os' import path from 'node:path' import { mkdtempSync } from 'node:fs' import { startAppwriteMock } from './support/appwriteMock.js' import { startFakeStripe } from './support/fakeStripe.js' import { useTestEnv } from './support/testEnv.js' import { schemaKeys } from './support/schema.js' import { mailSink } from './support/mailSink.js' // Etappe 4: Team-Mails oeffnen das Ticketsystem (Chat beim Kunden, Antrag im Kunden-Reiter Gutschriften) process.env.TAKEOVER_UPLOAD_DIR = mkdtempSync(path.join(os.tmpdir(), 'team-mail-links-')) process.env.CHAT_NOTIFY_EMAILS = 'team@webklar.invalid' const aw = await startAppwriteMock({ schema: { subscriptions: schemaKeys('subscriptions'), takeoverCredits: schemaKeys('takeoverCredits') }, }) const st = await startFakeStripe() useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url }) const { seedFixtures, hostingDoc, customers } = await import('./support/fixtures.js') const { setMailTransportForTests, sendChatNotification } = await import('../server/services/mailer.js') const { createTakeoverRequest, answerQuestion } = await import('../server/services/takeoverCredits.js') after(() => { setMailTransportForTests(null) return Promise.all([aw.close(), st.close()]) }) seedFixtures(aw) aw.seed('subscriptions', hostingDoc) let sink beforeEach(() => { sink = mailSink() setMailTransportForTests(sink) }) const teamMail = (subject) => sink.sent.find((m) => m.to.some((t) => t.address === 'team@webklar.invalid') && subject.test(m.subject)) const input = { email: 'k@example.invalid', services: ['hosting'], provider: 'Altanbieter', domain: '', invoiceAmountCents: 12000, billingMonths: 12, paidUntil: '2027-01-31', message: '', } test('T01 antwortet im Ticketsystem beim Kunden', async () => { const res = await sendChatNotification({ $id: 'c1', name: 'Berta' }, 'Hallo') assert.deepEqual(res, { sent: true }) const mail = teamMail(/Neue Portalnachricht von Berta/) assert.ok(mail) assert.match(mail.html, /href="https:\/\/ticket\.webklar\.com\/customers\/chat\?kunde=c1"[^>]*>Im Ticketsystem antworten →<\/a>/) assert.match(mail.html, /href="https:\/\/ticket\.webklar\.com\/customers"[^>]*>Ticketsystem<\/a>/) assert.doesNotMatch(mail.html, /admin\.html|Admin-Bereich/) }) test('T10/T11 oeffnen den Antrag im Kunden-Reiter Gutschriften', async () => { const doc = await createTakeoverRequest({ customer: customers.c1, input, uploads: [], consentIp: '127.0.0.1' }) const link = `https://ticket.webklar.com/customers/c1?tab=gutschriften&antrag=${doc.$id}` const t10 = teamMail(/Übernahmegutschrift/) assert.ok(t10, sink.sent.map((m) => m.subject).join(' | ')) assert.ok(t10.html.includes(`href="${link}"`), 'T10-Link') assert.doesNotMatch(t10.html, /admin\.html|Admin-Bereich/) aw.seed('takeoverCredits', { ...aw.docs('takeoverCredits').get(doc.$id), status: 'rueckfrage' }) sink.sent.length = 0 await answerQuestion({ customer: customers.c1, doc: aw.docs('takeoverCredits').get(doc.$id), message: 'Hier die Antwort', uploads: [] }) const t11 = sink.sent.find((m) => m.to.some((t) => t.address === 'team@webklar.invalid')) assert.ok(t11) assert.ok(t11.html.includes(`href="${link}"`), 'T11-Link') assert.doesNotMatch(t11.html, /admin\.html|Admin-Bereich/) })