import { test, after } from 'node:test'
import assert from 'node:assert/strict'
import express from 'express'
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import os from 'node:os'
import path from 'node:path'
import { startAppwriteMock } from './support/appwriteMock.js'
import { startFakeStripe } from './support/fakeStripe.js'
import { useTestEnv } from './support/testEnv.js'
import { schemaKeys } from './support/schema.js'
// Dashboard-Weiche: je Sitzung die neue Platzhalter-Seite oder bytegleich die alte (Schalter KUNDENANSICHT_NEU)
const aw = await startAppwriteMock({ schema: { customerViewLog: schemaKeys('customerViewLog') } })
const st = await startFakeStripe()
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
const { config } = await import('../server/config.js')
const { startTestApp, rawGet } = await import('./support/testApp.js')
const { customerCookie, kundenansichtCookie, adminCookie, viewAsCookie } = await import('./support/fixtures.js')
const { dashboardWeiche, neuDirektWeiche, oeffentlicheSeiteWeiche } = await import('../server/services/kundenansicht/dashboardWeiche.js')
const publicDir = fileURLToPath(new URL('../public/', import.meta.url))
const router = express.Router() // gleiche Reihenfolge wie server/index.js
router.get('/dashboard.html', dashboardWeiche({ publicDir }))
router.get('/neu/dashboard.html', neuDirektWeiche())
router.get(['/kuendigen.html', '/widerrufen.html'], oeffentlicheSeiteWeiche({ publicDir }))
router.use(express.static(publicDir))
// Nachtrag N39: dieselbe Weiche mit einem Nachbau von public/ (Datei fuer Datei erfunden), weil public/neu/oeffentlich/ erst mit P2 entsteht
const nachbau = mkdtempSync(path.join(os.tmpdir(), 'kn-weiche-'))
mkdirSync(path.join(nachbau, 'neu', 'oeffentlich'), { recursive: true })
writeFileSync(path.join(nachbau, 'neu', 'oeffentlich', 'kuendigen.html'), '
Nachbau')
const nachbauRouter = express.Router()
nachbauRouter.get(['/kuendigen.html', '/widerrufen.html'], oeffentlicheSeiteWeiche({ publicDir: nachbau }))
nachbauRouter.use(express.static(publicDir))
const app = await startTestApp({ '/nachbau': nachbauRouter, '/': router })
after(() => {
if (nachbau.startsWith(path.join(os.tmpdir(), 'kn-weiche-'))) rmSync(nachbau, { recursive: true, force: true })
return Promise.all([app.close(), aw.close(), st.close()])
})
const stelle = (mode, pilotEmails = []) => Object.assign(config.kundenansichtNeu, { mode, pilotEmails })
const ALT = readFileSync(path.join(publicDir, 'dashboard.html'), 'utf8')
const istNeu = (r) => r.status === 200 && String(r.body).includes('') // N5: gepinnt wird nur die Meta-Zeile
const istAlt = (r) => r.status === 200 && r.body === ALT
const MAIL = 'k@example.invalid' // E-Mail von c1; c2 hat k2@example.invalid
const UNSIGNIERT = `${config.cookieName}=${encodeURIComponent(JSON.stringify({ customerId: 'c1', appwriteUserId: 'u1', email: MAIL }))}`
const FAELLE = [ // [Name, Modus, Liste, Cookie, Ergebnis]
['Pilot, Kunde auf der Liste', 'pilot', [MAIL], customerCookie('c1'), 'neu'],
['Pilot, Kunde daneben', 'pilot', [MAIL], customerCookie('c2'), 'alt'],
['Pilot, Mitarbeiter-Kundenansicht', 'pilot', [], kundenansichtCookie(), 'neu'],
['off mit Stern, Kunde', 'off', ['*'], customerCookie('c1'), 'alt'],
['off mit Stern, Kundenansicht', 'off', ['*'], kundenansichtCookie(), 'alt'],
['on, Kunde', 'on', [], customerCookie('c1'), 'neu'],
['on, alte Mitarbeiter-Sitzung', 'on', [], adminCookie(), 'alt'],
['on, Kundenansicht ohne viewId', 'on', [], viewAsCookie('c1'), 'alt'],
['Pilot mit Stern, ohne Sitzung (200 wie heute, kein Redirect)', 'pilot', ['*'], undefined, 'alt'],
['Pilot mit Stern, unsigniertes Cookie', 'pilot', ['*'], UNSIGNIERT, 'alt'],
]
for (const [name, modus, liste, cookie, soll] of FAELLE) test(name, async () => {
stelle(modus, liste)
const r = await rawGet('/dashboard.html', { cookie })
assert.ok(soll === 'neu' ? istNeu(r) : istAlt(r), `${r.status} ${String(r.body).slice(0, 80)}`)
})
test('neue Seite: HTML und Cache-Control no-cache; Query bleibt erhalten', async () => {
stelle('pilot', [MAIL])
const r = await rawGet('/dashboard.html?abo=success', { cookie: customerCookie('c1') })
assert.ok(istNeu(r)); assert.equal(r.headers.get('cache-control'), 'no-cache'); assert.match(r.headers.get('content-type'), /^text\/html/)
})
test('Platzhalter trägt beide Marker (N5) und die Hülle des Briefs', () => {
const html = readFileSync(path.join(publicDir, 'neu', 'dashboard.html'), 'utf8')
for (const teil of ['', '', 'data-kn-platzhalter', 'id="kn-platzhalter-ansicht"', 'Kundenansicht neu', 'Platzhalter bis P1', '/api/auth/me']) assert.ok(html.includes(teil), teil)
assert.ok(!/