337 lines
20 KiB
JavaScript
337 lines
20 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'
|
|
import { schemaKeys } from './support/schema.js'
|
|
import { mailSink } from './support/mailSink.js'
|
|
|
|
const ANALYSE_KEYS = ['accentColor', 'avvVersion', 'avvAcceptedAt', 'avvAcceptedBy', 'activatedAt', 'offSince', 'privacyTicketId', 'activatedMailAt', 'avvConsentDate', 'avvConsentChannel', 'removalTicketId', 'publishTicketId', 'audienceConfirmed', 'audienceTextVersion']
|
|
const CONSENT_KEYS = ['customerId', 'projectId', 'siteKey', 'event', 'avvVersion', 'via', 'acceptedAt', 'acceptedBy', 'textformDate', 'textformChannel', 'audienceConfirmed', 'audienceTextVersion']
|
|
const aw = await startAppwriteMock({
|
|
schema: { portalFeatures: [...schemaKeys('portalFeatures'), ...ANALYSE_KEYS], subscriptions: schemaKeys('subscriptions'), analyseConsents: CONSENT_KEYS },
|
|
})
|
|
const st = await startFakeStripe()
|
|
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
|
|
const { config } = await import('../server/config.js')
|
|
const { startTestApp, get, rawGet, post, sessionCookie } = await import('./support/testApp.js')
|
|
const { customerCookie, wartungDoc, seedFixtures } = await import('./support/fixtures.js')
|
|
const { default: funktionenRoutes } = await import('../server/routes/funktionen.js')
|
|
const { default: adminAnalyseRoutes } = await import('../server/routes/admin/analyse.js')
|
|
const an = await import('../server/services/analyse.js')
|
|
const sf = await import('../server/services/siteFeatures.js')
|
|
const { verifyHeatToken } = await import('../analytics/src/heat.js')
|
|
const { createAnalyticsClient } = await import('../server/services/analyticsClient.js')
|
|
const { setMailTransportForTests } = await import('../server/services/mailer.js')
|
|
|
|
const app = await startTestApp({ '/api/funktionen': funktionenRoutes, '/api/admin/analyse': adminAnalyseRoutes })
|
|
setMailTransportForTests(mailSink())
|
|
after(() => {
|
|
setMailTransportForTests(null)
|
|
return Promise.all([app.close(), aw.close(), st.close()])
|
|
})
|
|
|
|
const puts = []
|
|
const statsCalls = []
|
|
let statsFail = false
|
|
const realClient = createAnalyticsClient({ heatSecret: 'h'.repeat(32), adminToken: 't' })
|
|
an.analyseDeps.client = {
|
|
putSite: async (siteKey, body) => puts.push({ siteKey, ...body }),
|
|
getStats: async (siteKey, range) => {
|
|
statsCalls.push({ siteKey, range })
|
|
if (statsFail) throw Object.assign(new Error('x'), { status: 502 })
|
|
return { pv: 5 }
|
|
},
|
|
heatToken: (a) => realClient.heatToken(a),
|
|
}
|
|
an.analyseDeps.rebuild = async () => {}
|
|
config.analyse.enabled = true
|
|
config.analyse.heatSecret = 'h'.repeat(32)
|
|
// Die Fassung 2026-10-02 liegt (je nach Uhr) noch in der Zukunft: Textform-Mindestdatum fuer die Tests auf frueh setzen
|
|
config.analyse.avvVersion = '2000-01-01'
|
|
|
|
seedFixtures(aw)
|
|
aw.seed('subscriptions', wartungDoc)
|
|
aw.seed('websiteProjects', { $id: 'p1', customerId: 'c1', projectName: 'Bäckerei', subdomain: 'baeckerei', liveDomain: 'baeckerei.de', isPublic: true })
|
|
aw.seed('websiteProjects', { $id: 'p2', customerId: 'c1', projectName: 'Privat', subdomain: 'privat', isPublic: false })
|
|
aw.seed('websiteProjects', { $id: 'p3', customerId: 'c1', projectName: 'Café', subdomain: 'cafe', isPublic: true })
|
|
aw.seed('websiteProjects', { $id: 'pd1', customerId: 'c1', projectName: 'Dev', subdomain: 'devsite', isPublic: true, previewDetected: 'dev:npm' })
|
|
aw.seed('websiteProjects', { $id: 'pd2', customerId: 'c1', projectName: 'Build', subdomain: 'buildsite', isPublic: true, previewDetected: 'build:npm' })
|
|
aw.seed('websiteProjects', { $id: 'p5', customerId: 'c2', projectName: 'Fremd', subdomain: 'fremd', isPublic: true })
|
|
|
|
const cookie = customerCookie('c1')
|
|
const A = '/api/funktionen/analyse'
|
|
const consent = () => ({ accepted: true, avvVersion: config.analyse.avvVersion })
|
|
const adminPost = (id, body, jwt = 'jwt-admin') => post(`/api/admin/analyse/${id}`, body, { headers: { Authorization: `Bearer ${jwt}` } })
|
|
const todayBerlin = () => new Intl.DateTimeFormat('sv-SE', { timeZone: 'Europe/Berlin' }).format(new Date())
|
|
const tf = (extra = {}) => ({ textformDate: todayBerlin(), textformChannel: 'chat', audienceConfirmed: true, ...extra })
|
|
const consentsOf = (p) => [...aw.docs('analyseConsents').values()].filter((d) => d.projectId === p).sort((a, b) => a.$seq - b.$seq)
|
|
const featureDoc = (c, p) => sf.getFeatureDoc(c, p, 'analyse')
|
|
|
|
beforeEach(() => {
|
|
puts.length = 0
|
|
statsCalls.length = 0
|
|
statsFail = false
|
|
config.analyse.enabled = true
|
|
})
|
|
|
|
test('Auth: ohne Anmeldung 401', async () => {
|
|
assert.equal((await post(`${A}/activate`, { projectId: 'p1' })).status, 401)
|
|
assert.equal((await rawGet(`${A}/stats?projectId=p1`)).status, 401)
|
|
assert.equal((await post(`${A}/heatmap-link`, {})).status, 401)
|
|
})
|
|
|
|
test('Eigentum: fremdes Projekt 403', async () => {
|
|
assert.equal((await post(`${A}/activate`, { projectId: 'p5', consent: consent() }, { cookie })).status, 403)
|
|
assert.equal((await post(`${A}/deactivate`, { projectId: 'p5' }, { cookie })).status, 403)
|
|
assert.equal((await rawGet(`${A}/stats?projectId=p5`, { cookie })).status, 403)
|
|
assert.equal((await post(`${A}/heatmap-link`, { projectId: 'p5', path: '/', vp: 'd' }, { cookie })).status, 403)
|
|
})
|
|
|
|
test('Schalter aus: alle Analyse-Routen 409', async () => {
|
|
config.analyse.enabled = false
|
|
for (const r of [
|
|
post(`${A}/activate`, { projectId: 'p1', consent: consent() }, { cookie }),
|
|
post(`${A}/deactivate`, { projectId: 'p1' }, { cookie }),
|
|
rawGet(`${A}/stats?projectId=p1`, { cookie }),
|
|
post(`${A}/heatmap-link`, { projectId: 'p1', path: '/', vp: 'd' }, { cookie }),
|
|
adminPost('p1', { on: true, ...tf() }),
|
|
]) {
|
|
const res = await r
|
|
assert.equal(res.status, 409)
|
|
assert.equal(res.body.error, 'Website-Analyse ist noch nicht freigeschaltet')
|
|
}
|
|
assert.equal(await featureDoc('c1', 'p1'), null)
|
|
})
|
|
|
|
test('GET /api/funktionen: analyse-Zustand je Projekt, mit und ohne Schalter', async () => {
|
|
const body = await get('/api/funktionen', { cookie })
|
|
const p = (id) => body.projects.find((x) => x.projectId === id)
|
|
assert.equal(p('p1').features.news.state, 'off')
|
|
assert.deepEqual(p('p1').analyse, { state: 'off', devMode: false, accentColor: '#111111', eligible: true, reason: null, reasonText: null, avvVersion: config.analyse.avvVersion, controller: { company: 'Kunde Eins', address: '', email: 'k@example.invalid', ok: true, missing: [] } })
|
|
assert.equal(p('p2').analyse.eligible, false)
|
|
assert.equal(p('p2').analyse.reason, 'nicht_oeffentlich')
|
|
assert.equal(p('p2').analyse.reasonText, an.ELIGIBILITY_MESSAGES.nicht_oeffentlich)
|
|
config.analyse.enabled = false
|
|
const off = await get('/api/funktionen', { cookie })
|
|
for (const x of off.projects) assert.deepEqual(x.analyse, { comingSoon: true })
|
|
assert.equal(off.projects[0].features.news.state, 'off')
|
|
})
|
|
|
|
test('Aktivieren und Deaktivieren (Kunde)', async () => {
|
|
const bad = await post(`${A}/activate`, { projectId: 'p1', accentColor: '#112233', consent: { accepted: false, avvVersion: config.analyse.avvVersion } }, { cookie })
|
|
assert.equal(bad.status, 400)
|
|
const ok = await post(`${A}/activate`, { projectId: 'p1', accentColor: '#112233', consent: consent() }, { cookie })
|
|
assert.equal(ok.status, 200)
|
|
assert.deepEqual(ok.body, { ok: true, state: 'active' })
|
|
assert.equal(puts[0].active, true)
|
|
assert.equal((await featureDoc('c1', 'p1')).accentColor, '#112233')
|
|
const view = (await get('/api/funktionen', { cookie })).projects.find((x) => x.projectId === 'p1').analyse
|
|
assert.equal(view.state, 'active')
|
|
assert.equal(view.accentColor, '#112233')
|
|
const off = await post(`${A}/deactivate`, { projectId: 'p1' }, { cookie })
|
|
assert.deepEqual(off.body, { ok: true, state: 'off' })
|
|
assert.equal(puts[1].active, false)
|
|
const notElig = await post(`${A}/activate`, { projectId: 'p2', consent: consent() }, { cookie })
|
|
assert.equal(notElig.status, 409)
|
|
})
|
|
|
|
test('Stats: Weiterleitung, Zeitraum, 503 bei Ausfall', async () => {
|
|
const p3 = await post(`${A}/activate`, { projectId: 'p3', consent: consent() }, { cookie })
|
|
assert.equal(p3.status, 200)
|
|
const key = (await featureDoc('c1', 'p3')).siteKey
|
|
const ok = await rawGet(`${A}/stats?projectId=p3&range=7`, { cookie })
|
|
assert.equal(ok.status, 200)
|
|
assert.deepEqual(ok.body, { pv: 5 })
|
|
assert.deepEqual(statsCalls[0], { siteKey: key, range: 7 })
|
|
assert.equal((await rawGet(`${A}/stats?projectId=p3&range=5`, { cookie })).status, 400)
|
|
statsFail = true
|
|
const down = await rawGet(`${A}/stats?projectId=p3`, { cookie })
|
|
assert.equal(down.status, 503)
|
|
assert.equal(down.body.error, 'Auswertung gerade nicht erreichbar')
|
|
statsFail = false
|
|
// aus, Daten noch da: weiter erlaubt
|
|
await post(`${A}/deactivate`, { projectId: 'p3' }, { cookie })
|
|
assert.equal((await rawGet(`${A}/stats?projectId=p3`, { cookie })).status, 200)
|
|
// nie aktiviert: keine Auswertung
|
|
aw.seed('websiteProjects', { $id: 'p6', customerId: 'c1', projectName: 'Neu', subdomain: 'neu', isPublic: true })
|
|
assert.equal((await rawGet(`${A}/stats?projectId=p6`, { cookie })).status, 409)
|
|
})
|
|
|
|
test('GET /api/funktionen: devMode nur bei aktiver Analyse eines Dev-Projekts', async () => {
|
|
const view = async (id) => (await get('/api/funktionen', { cookie })).projects.find((x) => x.projectId === id).analyse
|
|
assert.equal((await view('pd1')).devMode, false, 'nicht aktiv: kein Hinweis')
|
|
await post(`${A}/activate`, { projectId: 'pd1', consent: consent() }, { cookie })
|
|
await post(`${A}/activate`, { projectId: 'pd2', consent: consent() }, { cookie })
|
|
assert.equal((await view('pd1')).devMode, true)
|
|
assert.equal((await view('pd2')).devMode, false, 'node_build wird gemessen')
|
|
await post(`${A}/deactivate`, { projectId: 'pd1' }, { cookie })
|
|
await post(`${A}/deactivate`, { projectId: 'pd2' }, { cookie })
|
|
})
|
|
|
|
test('Heatmap-Link: Prüfung, URL, Token', async () => {
|
|
await post(`${A}/activate`, { projectId: 'p1', consent: consent() }, { cookie })
|
|
const key = (await featureDoc('c1', 'p1')).siteKey
|
|
const link = (b) => post(`${A}/heatmap-link`, { projectId: 'p1', ...b }, { cookie })
|
|
for (const path of ['start', '/a?x=1', '/a#b', '/' + 'a'.repeat(300), 5]) assert.equal((await link({ path, vp: 'd' })).status, 400, String(path))
|
|
assert.equal((await link({ path: '/', vp: 'x' })).status, 400)
|
|
const ok = await link({ path: '/preise', vp: 'm' })
|
|
assert.equal(ok.status, 200)
|
|
const url = new URL(ok.body.url)
|
|
assert.equal(url.origin, 'https://baeckerei.de')
|
|
assert.equal(url.pathname, '/preise')
|
|
const v = verifyHeatToken(url.searchParams.get('__wk_heat'), config.analyse.heatSecret, Date.now())
|
|
assert.equal(v.siteKey, key)
|
|
assert.equal(v.path, '/preise')
|
|
assert.equal(v.vp, 'm')
|
|
// ohne Live-Domain: Subdomain
|
|
await post(`${A}/activate`, { projectId: 'p3', consent: consent() }, { cookie })
|
|
const sub = await post(`${A}/heatmap-link`, { projectId: 'p3', path: '/', vp: 't' }, { cookie })
|
|
assert.equal(new URL(sub.body.url).origin, 'https://cafe.project.webklar.com')
|
|
// nicht aktiv: 409
|
|
await post(`${A}/deactivate`, { projectId: 'p3' }, { cookie })
|
|
assert.equal((await post(`${A}/heatmap-link`, { projectId: 'p3', path: '/', vp: 't' }, { cookie })).status, 409)
|
|
})
|
|
|
|
test('Admin: 401, 400, 200', async () => {
|
|
assert.equal((await post('/api/admin/analyse/p6', { on: true })).status, 401)
|
|
assert.equal((await adminPost('p6', { on: true, ...tf() }, 'jwt-kunde')).status, 403)
|
|
const noTf = await adminPost('p6', { on: true, audienceConfirmed: true, textformChannel: 'chat' })
|
|
assert.equal(noTf.status, 400)
|
|
assert.equal((await adminPost('p6', { on: true, ...tf({ textformDate: undefined }) })).status, 400)
|
|
assert.equal((await adminPost('p6', { on: true, ...tf({ textformChannel: undefined }) })).status, 400)
|
|
assert.equal((await adminPost('p6', { on: true, ...tf({ textformChannel: 'telefon' }) })).status, 400)
|
|
assert.equal((await adminPost('p6', { on: true, ...tf({ textformDate: '1999-01-01' }) })).status, 400, 'vor der Fassung')
|
|
assert.equal((await adminPost('p6', { on: true, ...tf({ audienceConfirmed: undefined }) })).status, 400)
|
|
const old = await adminPost('p6', { on: true, avvConfirmedVerbally: true, ...tf() })
|
|
assert.equal(old.status, 400)
|
|
assert.equal(old.body.error, 'Zustimmung in Textform nötig')
|
|
assert.equal(await featureDoc('c1', 'p6'), null, 'nichts angelegt')
|
|
assert.equal((await adminPost('p6', { on: 'ja' })).status, 400)
|
|
assert.equal((await adminPost('nix', { on: true, ...tf() })).status, 404)
|
|
const on = await adminPost('p6', { on: true, ...tf() })
|
|
assert.equal(on.status, 200)
|
|
assert.deepEqual(on.body, { ok: true, state: 'active' })
|
|
const d = await featureDoc('c1', 'p6')
|
|
assert.equal(d.avvAcceptedBy, 'kenso@webklar.com')
|
|
assert.equal(d.avvVersion, config.analyse.avvVersion)
|
|
assert.equal(d.avvConsentDate, todayBerlin())
|
|
assert.equal(d.avvConsentChannel, 'chat')
|
|
const h = consentsOf('p6')
|
|
assert.equal(h.length, 1)
|
|
assert.equal(h[0].via, 'woms')
|
|
assert.equal(h[0].acceptedBy, 'kenso@webklar.com')
|
|
assert.equal(h[0].audienceConfirmed, true)
|
|
assert.equal(h[0].audienceTextVersion, config.analyse.avvVersion)
|
|
assert.equal(d.audienceConfirmed, true)
|
|
assert.equal(h[0].textformDate, todayBerlin())
|
|
assert.equal(h[0].textformChannel, 'chat')
|
|
const off = await adminPost('p6', { on: false })
|
|
assert.deepEqual(off.body, { ok: true, state: 'off' })
|
|
})
|
|
|
|
test('Admin: Lesezugriff GET', async () => {
|
|
const adminGet = (id, jwt = 'jwt-admin') => rawGet(`/api/admin/analyse/${id}`, { headers: { Authorization: `Bearer ${jwt}` } })
|
|
assert.equal((await rawGet('/api/admin/analyse/p1')).status, 401)
|
|
assert.equal((await adminGet('p1', 'jwt-kunde')).status, 403)
|
|
assert.equal((await adminGet('nix')).status, 404)
|
|
await adminPost('p1', { on: false })
|
|
const off = await adminGet('p1')
|
|
assert.equal(off.status, 200)
|
|
assert.equal(off.body.enabled, true)
|
|
assert.equal(off.body.eligible, true)
|
|
assert.equal(off.body.reasonText, null)
|
|
assert.equal(off.body.avvVersion, config.analyse.avvVersion)
|
|
await adminPost('p1', { on: true, ...tf() })
|
|
const on = await adminGet('p1')
|
|
assert.equal(on.body.state, 'active')
|
|
assert.equal(on.body.avvConsentDate, todayBerlin())
|
|
assert.equal(on.body.avvConsentChannel, 'chat')
|
|
assert.deepEqual(on.body.privacy, { ok: true, missing: [] })
|
|
assert.equal(on.body.avvAcceptedBy, 'kenso@webklar.com')
|
|
assert.ok(on.body.activatedAt)
|
|
assert.ok(!('siteKey' in on.body) && !JSON.stringify(on.body).includes((await featureDoc('c1', 'p1')).siteKey))
|
|
const priv = await adminGet('p2')
|
|
assert.equal(priv.body.eligible, false)
|
|
assert.equal(priv.body.state, null)
|
|
assert.equal(priv.body.reasonText, 'Die Website-Analyse gibt es nur für öffentliche Websites.')
|
|
})
|
|
|
|
test('Fix a: Kunde ändert gesperrtes Dokument nicht, Mitarbeiter schon', async () => {
|
|
await adminPost('p6', { on: true, ...tf() })
|
|
const cur = await featureDoc('c1', 'p6')
|
|
await sf.disable(cur.$id, { by: 'Test' })
|
|
puts.length = 0
|
|
const r = await post(`${A}/deactivate`, { projectId: 'p6' }, { cookie })
|
|
assert.deepEqual(r.body, { ok: true, state: 'disabled' })
|
|
assert.equal((await featureDoc('c1', 'p6')).state, 'disabled')
|
|
const staff = await an.deactivateAnalyse({ customerId: 'c1', projectId: 'p6', by: 'Andrej' })
|
|
assert.equal(staff.doc.state, 'off')
|
|
})
|
|
|
|
test('Fix b: Abschalten durch Mitarbeiter meldet Sammeldienst active:false', async () => {
|
|
await adminPost('p6', { on: true, ...tf() })
|
|
const cur = await featureDoc('c1', 'p6')
|
|
puts.length = 0
|
|
await sf.disable(cur.$id, { by: 'Test' })
|
|
assert.equal(puts.length, 1)
|
|
assert.deepEqual(puts[0], { siteKey: cur.siteKey, projectId: 'p6', domains: ['neu.project.webklar.com'], active: false })
|
|
// Ausfall des Sammeldienstes verhindert das Abschalten nicht
|
|
const real = an.analyseDeps.client.putSite
|
|
an.analyseDeps.client.putSite = async () => { throw new Error('weg') }
|
|
const again = await sf.disable(cur.$id, { by: 'Test' })
|
|
an.analyseDeps.client.putSite = real
|
|
assert.equal(again.state, 'disabled')
|
|
})
|
|
|
|
test('Härtung: ungültige Hosts, Pfadzeichen, Fehler bei einem Projekt', async () => {
|
|
// analyseDomains: ungueltige Hosts werden uebersprungen
|
|
assert.deepEqual(an.analyseDomains({ subdomain: 'cafe', liveDomain: 'https://Cafe.DE/x' }), ['cafe.project.webklar.com', 'cafe.de', 'www.cafe.de'])
|
|
assert.deepEqual(an.analyseDomains({ subdomain: 'cafe', liveDomain: 'evil.de@x y' }), ['cafe.project.webklar.com'])
|
|
assert.deepEqual(an.analyseDomains({ subdomain: 'ca fe', liveDomain: 'a_b.de' }), [])
|
|
assert.deepEqual(an.analyseDomains({ subdomain: 'cafe', liveDomain: 'localhost' }), ['cafe.project.webklar.com'])
|
|
// Heatmap-Pfad: Steuerzeichen, Backslash, Leerraum => 400; dekodierte Form bleibt erlaubt
|
|
await post(`${A}/activate`, { projectId: 'p1', consent: consent() }, { cookie })
|
|
const link = (path) => post(`${A}/heatmap-link`, { projectId: 'p1', path, vp: 'd' }, { cookie })
|
|
for (const path of ['/a\\b', '/a b', '/a\nb', '/a\u0000b', '/a\tb', '/a\u007fb']) assert.equal((await link(path)).status, 400, JSON.stringify(path))
|
|
assert.equal((await link('/über-uns')).status, 200)
|
|
// keine gueltige Domain => Aktivieren scheitert mit 409, vor dem Sammeldienst
|
|
aw.seed('websiteProjects', { $id: 'p7', customerId: 'c1', projectName: 'Kaputt', subdomain: 'ka putt', liveDomain: 'x_y', isPublic: true })
|
|
const before = puts.length
|
|
const bad = await post(`${A}/activate`, { projectId: 'p7', consent: consent() }, { cookie })
|
|
assert.equal(bad.status, 409)
|
|
assert.equal(bad.body.error, 'Keine gültige Domain für die Analyse')
|
|
assert.equal(puts.length, before)
|
|
})
|
|
|
|
test('Kunden-Aktivierung schreibt Historie mit Sitzungsnamen; fehlende Angaben: controller + 409', async () => {
|
|
aw.seed('customers', { $id: 'c9', appwriteUserId: 'u9', email: 'neun', name: '', status: 'active', portalAccessEnabled: true })
|
|
aw.seed('websiteProjects', { $id: 'p9', customerId: 'c9', projectName: 'Leer', subdomain: 'leer', isPublic: true })
|
|
aw.seed('subscriptions', { ...wartungDoc, $id: 'sub_w_c9', stripeSubscriptionId: 'sub_w_c9', customerId: 'c9' })
|
|
const c9 = sessionCookie({ customerId: 'c9', appwriteUserId: 'u9', name: 'Neun', email: 'neun' })
|
|
const view = (await get('/api/funktionen', { cookie: c9 })).projects.find((x) => x.projectId === 'p9').analyse
|
|
assert.deepEqual(view.controller, { company: '', address: '', email: 'neun', ok: false, missing: ['firma', 'email'] })
|
|
const r = await post(`${A}/activate`, { projectId: 'p9', consent: consent() }, { cookie: c9 })
|
|
assert.equal(r.status, 409)
|
|
assert.match(r.body.error, /fehlen in Deinen Kundendaten Firma oder Name/)
|
|
assert.equal(consentsOf('p9').length, 0)
|
|
const before = consentsOf('p3').length
|
|
await post(`${A}/activate`, { projectId: 'p3', consent: consent() }, { cookie })
|
|
const h = consentsOf('p3')
|
|
assert.equal(h.length, before + 1)
|
|
assert.equal(h.at(-1).acceptedBy, 'Kunde Eins <k@example.invalid>')
|
|
assert.equal(h.at(-1).audienceConfirmed, true)
|
|
assert.equal(h.at(-1).via, 'portal')
|
|
const admin = (await rawGet('/api/admin/analyse/p9', { headers: { Authorization: 'Bearer jwt-admin' } })).body
|
|
assert.deepEqual(admin.privacy, { ok: false, missing: ['firma', 'email'] })
|
|
})
|
|
|
|
test('Admin-Sitzung (Impersonation): handelnde Person ist der Admin, nicht der Kunde', async () => {
|
|
aw.seed('websiteProjects', { $id: 'p20', customerId: 'c1', projectName: 'Imp', subdomain: 'imp', isPublic: true })
|
|
const c = sessionCookie({ customerId: 'c1', appwriteUserId: 'u1', name: 'Kunde Eins', email: 'k@example.invalid', adminName: 'Kenso', adminEmail: 'kenso@webklar.com' })
|
|
assert.equal((await post(`${A}/activate`, { projectId: 'p20', consent: consent() }, { cookie: c })).status, 200)
|
|
const h = consentsOf('p20')
|
|
assert.equal(h[0].acceptedBy, 'Kenso <kenso@webklar.com>')
|
|
assert.equal((await featureDoc('c1', 'p20')).avvAcceptedBy, 'Kenso <kenso@webklar.com>')
|
|
})
|