Kundenansicht: Beenden mit Rueckweg ins Ticketsystem, /me mit Ansichts-Kennung, Team-Routen Portal-Status, Protokoll, Preview-Link
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7d8ba56088
commit
c5afd42a5f
9 files changed
+284
-23
No files matched your search
@@ -0,0 +1,89 @@
|
||||
import { test, after } 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'
|
||||
|
||||
// Kundenansicht beenden (Rueckweg ins Ticketsystem) und /api/auth/me in der Kundenansicht
|
||||
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, get, post } = await import('./support/testApp.js')
|
||||
const { seedFixtures, kundenansichtCookie, viewAsCookie } = await import('./support/fixtures.js')
|
||||
const { kundenansichtGuard } = await import('../server/middleware/kundenansichtGuard.js')
|
||||
const { default: authRoutes } = await import('../server/routes/auth.js')
|
||||
const { verifyPreviewSessionToken } = await import('../server/services/previewSession.js')
|
||||
const app = await startTestApp({ '/': kundenansichtGuard, '/api/auth': authRoutes })
|
||||
after(() => Promise.all([app.close(), aw.close(), st.close()]))
|
||||
|
||||
seedFixtures(aw)
|
||||
|
||||
const kv = (extra = {}) => ({ cookie: kundenansichtCookie(extra), headers: { 'x-kundenansicht': extra.viewId || 'a'.repeat(32) } })
|
||||
const clears = (res, name) => res.headers.getSetCookie().some((c) => c.startsWith(`${name}=`) && /Expires=Thu, 01 Jan 1970/.test(c))
|
||||
const cookieValue = (res, name) => {
|
||||
const c = res.headers.getSetCookie().find((x) => x.startsWith(`${name}=`))
|
||||
return c ? decodeURIComponent(c.split(';')[0].slice(name.length + 1)) : null
|
||||
}
|
||||
const logOf = (action) => [...aw.docs('customerViewLog').values()].filter((d) => d.action === action)
|
||||
const me = async (cookie) => {
|
||||
const res = await fetch(`${app.url}/api/auth/me`, { headers: { cookie } })
|
||||
return { status: res.status, body: await res.json(), headers: res.headers }
|
||||
}
|
||||
|
||||
test('Beenden: Protokoll beendet, beide Cookies geloescht, Rueckweg zur Kundenseite im WOMS', async () => {
|
||||
const before = logOf('beendet').length
|
||||
const res = await post('/api/auth/kundenansicht/ende', {}, kv({ viewId: 'b'.repeat(32) }))
|
||||
assert.equal(res.status, 200)
|
||||
assert.equal(res.body.redirect, 'https://ticket.webklar.com/customers/c1')
|
||||
assert.ok(clears(res, config.cookieName))
|
||||
assert.ok(clears(res, 'preview_session'))
|
||||
const ended = logOf('beendet')
|
||||
assert.equal(ended.length, before + 1)
|
||||
assert.deepEqual([ended.at(-1).customerId, ended.at(-1).staffName], ['c1', 'Andrej'])
|
||||
})
|
||||
|
||||
test('Beenden ohne Kundenansicht -> Rueckweg /customers, kein Protokoll', async () => {
|
||||
const before = logOf('beendet').length
|
||||
const res = await post('/api/auth/kundenansicht/ende', {})
|
||||
assert.equal(res.status, 200)
|
||||
assert.equal(res.body.redirect, 'https://ticket.webklar.com/customers')
|
||||
assert.equal(logOf('beendet').length, before)
|
||||
})
|
||||
|
||||
test('/me in neuer Ansicht: viewId, viewExpiresAt, admin.name, Preview-Cookie nur fuer den Kunden', async () => {
|
||||
const viewExpiresAt = Date.now() + 30 * 60 * 1000
|
||||
const res = await me(kundenansichtCookie({ viewId: 'c'.repeat(32), viewExpiresAt }))
|
||||
assert.equal(res.status, 200)
|
||||
assert.equal(res.body.authenticated, true)
|
||||
assert.equal(res.body.viewAs, true)
|
||||
assert.equal(res.body.viewId, 'c'.repeat(32))
|
||||
assert.equal(res.body.viewExpiresAt, viewExpiresAt)
|
||||
assert.equal(res.body.admin.name, 'Andrej')
|
||||
assert.equal(res.body.customer.id, 'c1')
|
||||
const preview = await verifyPreviewSessionToken(cookieValue(res, 'preview_session'))
|
||||
assert.deepEqual([preview.role, preview.customerId], ['customer', 'c1'])
|
||||
assert.ok(preview.exp <= Math.ceil(viewExpiresAt / 1000) + 1, 'Preview endet mit der Ansicht')
|
||||
})
|
||||
|
||||
test('/me abgelaufen -> authenticated false, reason view_expired, Protokoll abgelaufen einmal', async () => {
|
||||
const before = logOf('abgelaufen').length
|
||||
const cookie = kundenansichtCookie({ viewId: 'd'.repeat(32), viewExpiresAt: Date.now() - 1000 })
|
||||
for (let i = 0; i < 2; i += 1) {
|
||||
const res = await me(cookie)
|
||||
assert.equal(res.status, 200)
|
||||
assert.equal(res.body.authenticated, false)
|
||||
assert.equal(res.body.reason, 'view_expired')
|
||||
assert.equal(res.body.message, 'Die Kundenansicht ist abgelaufen. Bitte im Ticketsystem erneut öffnen.')
|
||||
assert.ok(clears(res, config.cookieName))
|
||||
}
|
||||
assert.equal(logOf('abgelaufen').length, before + 1)
|
||||
})
|
||||
|
||||
test('/me alte Ansicht (viewAsCookie) unveraendert: viewAs true, keine viewId', async () => {
|
||||
const body = await get('/api/auth/me', { cookie: viewAsCookie('c1') })
|
||||
assert.equal(body.viewAs, true)
|
||||
assert.equal(body.viewId, undefined)
|
||||
assert.equal(body.admin.name, 'Kenso')
|
||||
})
|
||||
Reference in new issue
Block a user