Files
ClaudeandClaude Opus 5.5 9ed295946c Website-Analyse für webklar.com: Sie-Fassung des Banners, fester Messdienst-Eintrag, Auswertung fürs WOMS
- Messskript: data-variant="eigen" zeigt eine eigene Banner-Fassung (Sie-Form, WEBklar misst selbst,
  BANNER_VERSION_EIGEN 2026-10-17); Kunden-Websites bleiben bei der Fassung 2026-10-02.
- config.analyse.eigeneWebsite: fester Schlüssel und Domains von webklar.com; ensureEigeneWebsite zieht den
  Eintrag im Messdienst täglich nach (aktiv: false schaltet ab). Kein Kunde, kein Abo, keine Tickets.
- /api/admin/analyse-eigen (jeder Mitarbeiter): Kennzahlen 7/30/90 Tage und Heatmap-Link auf webklar.com.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 18:34:06 +00:00

97 lines
4.9 KiB
JavaScript

import { test, after, beforeEach } from 'node:test'
import assert from 'node:assert/strict'
import { startAppwriteMock } from './support/appwriteMock.js'
import { startFakeStripe } from './support/fakeStripe.js'
import { useTestEnv } from './support/testEnv.js'
// Website-Analyse der eigenen Website webklar.com: fester Messdienst-Eintrag und Auswertung fuers WOMS (/api/admin/analyse-eigen).
const aw = await startAppwriteMock()
const st = await startFakeStripe()
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
const { config } = await import('../server/config.js')
const { startTestApp, rawGet, post } = await import('./support/testApp.js')
const { default: routes } = await import('../server/routes/admin/analyseEigen.js')
const eigen = await import('../server/services/analyseEigen.js')
const app = await startTestApp({ '/api/admin/analyse-eigen': routes })
const vorher = { ...config.analyse.eigeneWebsite }
after(() => {
Object.assign(config.analyse.eigeneWebsite, vorher)
return Promise.all([app.close(), aw.close(), st.close()])
})
const aufrufe = []
let statsFehler = null
eigen.eigenDeps.client = {
putSite: async (siteKey, body) => aufrufe.push({ op: 'put', siteKey, ...body }),
stopSite: async (siteKey) => aufrufe.push({ op: 'stop', siteKey }),
getStats: async (siteKey, range) => {
if (statsFehler) throw statsFehler
aufrufe.push({ op: 'stats', siteKey, range })
return { range, totals: { pv: 12 } }
},
heatToken: ({ siteKey, path, vp }) => `tok:${siteKey}:${path}:${vp}`,
}
const staff = { headers: { Authorization: 'Bearer jwt-staff' } }
const W = config.analyse.eigeneWebsite
beforeEach(() => {
aufrufe.length = 0
statsFehler = null
Object.assign(config.analyse.eigeneWebsite, vorher)
})
test('Konfiguration: gueltiger Schluessel und Domains, wie sie der Messdienst annimmt', () => {
assert.match(W.siteKey, /^[a-z0-9]{16,40}$/)
assert.equal(W.aktiv, true)
assert.equal(W.host, 'webklar.com')
assert.deepEqual(W.domains, ['webklar.com', 'www.webklar.com'])
assert.ok(W.projectId.length > 0 && W.projectId.length <= 100)
})
test('ensureEigeneWebsite: legt den Eintrag an bzw. zieht ihn nach; aktiv false schaltet ab', async () => {
assert.deepEqual(await eigen.ensureEigeneWebsite(), { aktiv: true })
assert.deepEqual(aufrufe, [{ op: 'put', siteKey: W.siteKey, projectId: W.projectId, domains: W.domains, active: true }])
aufrufe.length = 0
config.analyse.eigeneWebsite.aktiv = false
assert.deepEqual(await eigen.ensureEigeneWebsite(), { aktiv: false })
assert.deepEqual(aufrufe, [{ op: 'stop', siteKey: W.siteKey }])
})
test('GET: nur fuer Mitarbeiter', async () => {
assert.equal((await rawGet('/api/admin/analyse-eigen')).status, 401)
assert.equal((await rawGet('/api/admin/analyse-eigen', { headers: { Authorization: 'Bearer jwt-kunde' } })).status, 403)
assert.equal((await rawGet('/api/admin/analyse-eigen', { headers: { Authorization: 'Bearer jwt-admin' } })).status, 200)
assert.deepEqual(aufrufe.map((a) => a.op), ['stats'])
})
test('GET: Auswertung mit Zeitraum, Adresse und Zustand', async () => {
const r = await rawGet('/api/admin/analyse-eigen?range=7', staff)
assert.equal(r.status, 200)
assert.deepEqual(r.body, { website: { host: 'webklar.com', aktiv: true }, stats: { range: 7, totals: { pv: 12 } } })
assert.deepEqual(aufrufe, [{ op: 'stats', siteKey: W.siteKey, range: 7 }])
assert.equal((await rawGet('/api/admin/analyse-eigen', staff)).body.stats.range, 30, 'Vorgabe 30 Tage')
for (const bad of ['1', '31', 'abc', '30x']) assert.equal((await rawGet(`/api/admin/analyse-eigen?range=${bad}`, staff)).status, 400)
})
test('GET: Messdienst ohne Eintrag => 409, nicht erreichbar => 503 ohne Details', async () => {
statsFehler = Object.assign(new Error('Auswertung antwortet mit Fehler 404'), { status: 404 })
const a = await rawGet('/api/admin/analyse-eigen', staff)
assert.equal(a.status, 409)
assert.match(a.body.error, /noch nicht eingerichtet/)
statsFehler = Object.assign(new Error('Auswertung nicht erreichbar'), { status: 502 })
const b = await rawGet('/api/admin/analyse-eigen', staff)
assert.deepEqual([b.status, b.body.error], [503, 'Auswertung gerade nicht erreichbar'])
})
test('POST heatmap-link: Link auf webklar.com mit Token; Pfad und Ansicht werden geprueft', async () => {
const r = await post('/api/admin/analyse-eigen/heatmap-link', { path: '/wartungs-abo', vp: 'm' }, staff)
assert.equal(r.status, 200)
assert.equal(r.body.url, `https://webklar.com/wartungs-abo?__wk_heat=${encodeURIComponent(`tok:${W.siteKey}:/wartungs-abo:m`)}`)
for (const path of ['wartungs-abo', '/a?b=1', '/a#x', '/a b', '/a\\b', `/${'x'.repeat(300)}`, 5, null]) {
assert.equal((await post('/api/admin/analyse-eigen/heatmap-link', { path, vp: 'd' }, staff)).status, 400, String(path))
}
assert.equal((await post('/api/admin/analyse-eigen/heatmap-link', { path: '/', vp: 'x' }, staff)).status, 400)
assert.equal((await post('/api/admin/analyse-eigen/heatmap-link', { path: '/', vp: 'd' })).status, 401)
})