import { test, before, after, beforeEach } from 'node:test'
import assert from 'node:assert/strict'
import express from 'express'
import { startFakeAppwrite } from './helpers/fakeAppwrite.js'
let fake
let server
let baseUrl
let createPushTimeToken
let resetPushTimeRateLimitForTests
let isRateLimited
let rateLimitSize
const gitSheet = (id, extra = {}) => ({
$id: id, wsid: '100300', woid: '100118', workorderId: 't1', serviceType: 'GIT',
employeeName: 'knso', endDate: '30.09.2026', endTime: '1646', startDate: '30.09.2026', startTime: '',
totalTime: 0, isComment: true,
details: 'Git Push auf `WEBklar/amin-friseur` (Branch: main)\nCommit: abc1234\n\n- [abc1234](https://git/x): Startseite neu (knso)',
...extra,
})
before(async () => {
fake = await startFakeAppwrite({
seed: {
workorders: [{ $id: 't1', woid: '100118', customerName: 'Amin Friseur' }],
worksheets: [
gitSheet('open1'),
gitSheet('open2'),
gitSheet('open3'),
gitSheet('done1', { startTime: '1500', totalTime: 45, isComment: false }),
gitSheet('evil', { details: 'Git Push auf `X` (Branch: main)\n\n- [abc1234](u): fett' }),
{ $id: 'remote1', serviceType: 'Remote', startTime: '', totalTime: 0 },
],
},
})
Object.assign(process.env, {
APPWRITE_ENDPOINT: fake.endpoint,
APPWRITE_API_KEY: 'test-key',
PUSH_TIME_SECRET: 'r'.repeat(40),
})
const routes = await import('../server/routes/pushTime.js')
resetPushTimeRateLimitForTests = routes.resetPushTimeRateLimitForTests
isRateLimited = routes.isRateLimited
rateLimitSize = routes.pushTimeRateLimitSizeForTests
;({ createPushTimeToken } = await import('../server/services/pushTimeToken.js'))
const app = express()
app.use('/zeit', express.urlencoded({ extended: false, limit: '4kb' }), routes.default)
server = await new Promise((resolve) => {
const s = app.listen(0, '127.0.0.1', () => resolve(s))
})
baseUrl = `http://127.0.0.1:${server.address().port}`
})
after(async () => {
if (server) await new Promise((resolve) => server.close(resolve))
await fake.close()
})
beforeEach(() => resetPushTimeRateLimitForTests?.())
const token = (worksheetId, now) => createPushTimeToken({ worksheetId, employeeId: 'k' }, now)
async function get(path) {
const res = await fetch(`${baseUrl}${path}`)
return { status: res.status, html: await res.text(), headers: res.headers }
}
async function post(path, form) {
const res = await fetch(`${baseUrl}${path}`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(form).toString(),
})
return { status: res.status, html: await res.text(), headers: res.headers }
}
test('GET speichert nie', async () => {
const t = token('open1')
for (const m of ['15', '30', '45', '60', '90', '120', '180', '']) {
const r = await get(`/zeit/${t}${m ? `?min=${m}` : ''}`)
assert.equal(r.status, 200)
assert.match(r.html, /#100118/)
assert.match(r.html, /Amin Friseur/)
assert.match(r.html, /WEBklar\/amin-friseur/)
assert.match(r.html, /Startseite neu/)
}
const ws = fake.get('worksheets', 'open1')
assert.equal(ws.totalTime, 0)
assert.equal(ws.startTime, '')
})
test('GET: Auswahl in 15-Minuten-Schritten, min=90 vorausgewählt, sonst 1 Std', async () => {
const t = token('open1')
const html = (await get(`/zeit/${t}?min=90`)).html
assert.match(html, /