// Preview-Bereitschaft: echter Zustand statt hasPreview (Standardwert false sperrte Previews) import { test, before, after } from 'node:test' import assert from 'node:assert/strict' import express from 'express' import cookieParser from 'cookie-parser' import { startFakeAppwrite } from './helpers/fakeAppwrite.js' import { isPreviewProjectReady } from '../server/services/previewReadiness.js' const base = { subdomain: 'kunde-a', projectType: 'website', provisioningStatus: 'deployed', hasPreview: false } test('hasPreview false + deployed/ready + Subdomain => bereit', () => { assert.equal(isPreviewProjectReady(base), true) assert.equal(isPreviewProjectReady({ ...base, provisioningStatus: undefined, status: 'Ready' }), true) }) test('kein Projekt / keine Subdomain => nicht bereit', () => { assert.equal(isPreviewProjectReady(null), false) assert.equal(isPreviewProjectReady({ ...base, subdomain: '' }), false) assert.equal(isPreviewProjectReady({ ...base, subdomain: ' ' }), false) }) test('previewMode off => nicht bereit', () => { assert.equal(isPreviewProjectReady({ ...base, previewMode: 'off' }), false) assert.equal(isPreviewProjectReady({ ...base, previewMode: 'dev' }), true) }) test('projectType repo/project => nicht bereit', () => { assert.equal(isPreviewProjectReady({ ...base, projectType: 'repo' }), false) assert.equal(isPreviewProjectReady({ ...base, projectType: 'project' }), false) }) test('Status pending/leer => nicht bereit', () => { assert.equal(isPreviewProjectReady({ ...base, provisioningStatus: 'pending' }), false) assert.equal(isPreviewProjectReady({ ...base, provisioningStatus: '', status: '' }), false) }) let aw, server, baseUrl, token before(async () => { aw = await startFakeAppwrite({ seed: { websiteProjects: [{ $id: 'p1', customerId: 'c1', ...base }] }, }) Object.assign(process.env, { APPWRITE_ENDPOINT: aw.endpoint, APPWRITE_API_KEY: 'test-key', PREVIEW_SESSION_SECRET: 'x'.repeat(40) }) const { createPreviewSessionToken } = await import('../server/services/previewSession.js') token = { c1: await createPreviewSessionToken({ userId: 'u1', customerId: 'c1', email: 'a@b.de' }), c2: await createPreviewSessionToken({ userId: 'u2', customerId: 'c2', email: 'c@d.de' }), } const { default: auth } = await import('../server/routes/auth.js') const app = express() app.use(cookieParser()) app.use('/api/auth', auth) server = await new Promise((r) => { const s = app.listen(0, '127.0.0.1', () => r(s)) }) baseUrl = `http://127.0.0.1:${server.address().port}` }) after(async () => { server.closeAllConnections() await new Promise((r) => server.close(r)) await aw.close() }) const access = async (t) => { const res = await fetch(`${baseUrl}/api/auth/preview-access?subdomain=kunde-a`, { headers: { Cookie: `preview_session=${t}` } }) return res.json() } test('Route: eigener Kunde, hasPreview false, deployed => allowed', async () => { assert.equal((await access(token.c1)).allowed, true) }) test('Route: anderer Kunde bleibt ausgesperrt', async () => { const r = await access(token.c2) assert.equal(r.allowed, false) assert.equal(r.reason, 'no_project') }) test('Route: archiviertes Projekt ist fuer den Kunden gesperrt (Entscheidung 2026-10-04)', async () => { const doc = aw.all('websiteProjects').find((d) => d.$id === 'p1') doc.archived = true try { const r = await access(token.c1) assert.equal(r.allowed, false) assert.equal(r.reason, 'no_project') } finally { doc.archived = false } })