import { test, before, after } from 'node:test'
import assert from 'node:assert/strict'
import { startFakeAppwrite } from './helpers/fakeAppwrite.js'
import { mailSink } from './support/mailSink.js'
let fake
let findEmployeeForPusher, buildPushTimeMail, sendPushTimeMail
let renderMail, verifyPushTimeToken, setMailTransportForTests
const KENSO = { $id: 'k', displayName: 'Kenso Grimm', shortcode: 'KNSO', email: 'kenso@webklar.com', $createdAt: '2026-01-01T00:00:00.000Z' }
const ANDREJ = { $id: 'a', displayName: 'Andrej Stevanovski', shortcode: 'ANDJ', email: '', $createdAt: '2026-01-02T00:00:00.000Z' }
const ticket = { $id: 't1', woid: '100118', customerName: 'Amin Friseur', topic: 'Website Amin Friseur', details: 'Neue Seite', status: 'Occupied' }
const worksheet = { $id: 'ws9', woid: '100118', serviceType: 'GIT' }
const commits = [
{ id: 'abc1234def', message: 'Startseite: Hero neu\n\nlanger Text' },
{ id: 'def5678abc', message: ' & Co' },
]
const input = (extra = {}) => ({
ticket, worksheet, repoFullName: 'WEBklar/amin-friseur', branch: 'main', commits,
pushedAt: new Date('2026-09-30T14:46:00Z'), ...extra,
})
before(async () => {
fake = await startFakeAppwrite({ seed: { employees: [ANDREJ, KENSO] } })
Object.assign(process.env, {
APPWRITE_ENDPOINT: fake.endpoint,
APPWRITE_API_KEY: 'test-key',
PUSH_TIME_SECRET: 'z'.repeat(40),
})
;({ findEmployeeForPusher, buildPushTimeMail, sendPushTimeMail } = await import('../server/services/pushTimeMail.js'))
;({ renderMail } = await import('../server/services/mailTemplates.js'))
;({ verifyPushTimeToken } = await import('../server/services/pushTimeToken.js'))
;({ setMailTransportForTests } = await import('../server/services/mailer.js'))
})
after(async () => {
setMailTransportForTests?.(null)
await fake.close()
})
test('findEmployeeForPusher: Kürzel, voller Name, ohne E-Mail, unbekannt', () => {
const employees = [ANDREJ, KENSO]
assert.equal(findEmployeeForPusher({ username: 'knso' }, employees)?.$id, 'k')
assert.equal(findEmployeeForPusher({ full_name: ' kenso grimm ' }, employees)?.$id, 'k')
assert.equal(findEmployeeForPusher({ login: 'ANDJ' }, employees), null)
assert.equal(findEmployeeForPusher({ username: 'fremd' }, employees), null)
assert.equal(findEmployeeForPusher({}, employees), null)
})
test('buildPushTimeMail: Betreff, Links, Escaping, gültiger Token', () => {
const mail = buildPushTimeMail({ employee: KENSO, ...input() })
assert.equal(mail.template, 'T15')
const out = renderMail('T15', mail.values)
assert.deepEqual(out.problems, [])
assert.equal(out.subject, '[Zeit] #100118 Amin Friseur – 2 Commit(s)')
assert.match(out.html, /Hallo Kenso,/)
assert.match(out.html, /In Arbeit/)
assert.match(out.html, /30\.09\.2026 16:46/)
for (const m of [15, 30, 45, 60, 90, 120, 180]) {
assert.match(out.html, new RegExp(`/zeit/[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\?min=${m}"`))
}
assert.match(out.html, /\/zeit\/[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+"/, 'Andere Zeit ohne min')
assert.match(out.html, /https:\/\/ticket\.webklar\.com\/tickets\?woid=100118/)
assert.match(out.html, /abc1234 Startseite: Hero neu/)
assert.doesNotMatch(out.html, /langer Text/)
assert.match(out.html, /<script>x<\/script> & Co/)
assert.doesNotMatch(out.html, /