Aufträge L5: Test – in der Kundenansicht ist das Bestätigen von Aufträgen gesperrt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
503337d7ae
commit
22a7c8123d
1 file changed
+89
@@ -0,0 +1,89 @@
|
|||||||
|
import { test, after, beforeEach } from 'node:test'
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import os from 'node:os'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { mkdtempSync } from 'node:fs'
|
||||||
|
import { startAppwriteMock } from './support/appwriteMock.js'
|
||||||
|
import { useTestEnv } from './support/testEnv.js'
|
||||||
|
import { mailSink } from './support/mailSink.js'
|
||||||
|
import { AUFTRAEGE_DATETIMES, AUFTRAEGE_SCHEMA, TOKEN, abDokument } from './auftraegeBestaetigungHilfe.js'
|
||||||
|
|
||||||
|
// Kundenansicht (Mitarbeiter im Portal eines Kunden): Bestätigen ist eine Erklärung im Namen des Kunden und bleibt gesperrt
|
||||||
|
process.env.AUFTRAEGE_UPLOAD_DIR = mkdtempSync(path.join(os.tmpdir(), 'auftraege-kundenansicht-'))
|
||||||
|
process.env.AUFTRAEGE_ENABLED = 'on'
|
||||||
|
const aw = await startAppwriteMock({ schema: AUFTRAEGE_SCHEMA, datetimes: AUFTRAEGE_DATETIMES, defaultLimit: 25 })
|
||||||
|
useTestEnv({ appwriteUrl: aw.url, stripeUrl: 'http://127.0.0.1:1' })
|
||||||
|
const { startTestApp, send } = await import('./support/testApp.js')
|
||||||
|
const { seedFixtures, customerCookie, kundenansichtCookie } = await import('./support/fixtures.js')
|
||||||
|
const { auftragToDoc, getAuftrag } = await import('../server/services/auftraege/auftragStore.js')
|
||||||
|
const { speicherePdf } = await import('../server/services/auftraege/ablage.js')
|
||||||
|
const { kundenansichtGuard, KUNDENANSICHT_ALLOWED } = await import('../server/middleware/kundenansichtGuard.js')
|
||||||
|
const { setMailTransportForTests } = await import('../server/services/mailer.js')
|
||||||
|
const { default: kundeRoutes } = await import('../server/routes/auftraegeKunde.js')
|
||||||
|
const { default: tokenRoutes } = await import('../server/routes/auftrag.js')
|
||||||
|
// Mount-Pfade und Reihenfolge wie in server/index.js: der Wächter steht vor den Routen
|
||||||
|
const app = await startTestApp({ '/': kundenansichtGuard, '/api/auftraege': kundeRoutes, '/api/auftrag': tokenRoutes })
|
||||||
|
after(() => {
|
||||||
|
setMailTransportForTests(null)
|
||||||
|
return Promise.all([app.close(), aw.close()])
|
||||||
|
})
|
||||||
|
seedFixtures(aw)
|
||||||
|
await speicherePdf('c1', 'ab1', Buffer.from('%PDF-1.4 Test'))
|
||||||
|
|
||||||
|
const VIEW = 'a'.repeat(32)
|
||||||
|
const kv = () => ({ cookie: kundenansichtCookie({ customerId: 'c1', viewId: VIEW }), headers: { 'x-kundenansicht': VIEW } })
|
||||||
|
let sink
|
||||||
|
beforeEach(() => {
|
||||||
|
sink = mailSink()
|
||||||
|
setMailTransportForTests(sink)
|
||||||
|
aw.seed('auftraege', { $id: 'ab1', ...auftragToDoc(abDokument()) })
|
||||||
|
})
|
||||||
|
const unveraendert = async () => {
|
||||||
|
const doc = await getAuftrag('ab1')
|
||||||
|
assert.deepEqual([doc.status, doc.bestaetigtAm, sink.sent.length], ['versendet', null, 0])
|
||||||
|
}
|
||||||
|
|
||||||
|
test('kein Eintrag der Erlaubnisliste gilt für Aufträge', () => {
|
||||||
|
for (const pfad of ['/api/auftraege', '/api/auftraege/ab1/bestaetigen', '/api/auftraege/ab1/pdf', `/api/auftrag/${TOKEN}`, `/api/auftrag/${TOKEN}/bestaetigen`]) {
|
||||||
|
assert.ok(!KUNDENANSICHT_ALLOWED.some(([, muster]) => muster.test(pfad)), pfad)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('POST /api/auftraege/:id/bestaetigen in der Kundenansicht: 403 view_blocked, die AB bleibt unverändert', async () => {
|
||||||
|
const res = await send('POST', '/api/auftraege/ab1/bestaetigen', { ...kv(), body: { bestaetigt: true, fruehbeginn: true } })
|
||||||
|
assert.equal(res.status, 403)
|
||||||
|
assert.equal(res.body.code, 'view_blocked')
|
||||||
|
await unveraendert()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('alle Schreib-Routen des Kunden-Routers sind in der Kundenansicht gesperrt (nur Bestätigen ist eine)', async () => {
|
||||||
|
const schreibRouten = kundeRoutes.stack
|
||||||
|
.filter((schicht) => schicht.route)
|
||||||
|
.flatMap((schicht) => Object.keys(schicht.route.methods).filter((m) => !['get', 'head', 'options', '_all'].includes(m)).map((m) => [m.toUpperCase(), `/api/auftraege${String(schicht.route.path).replace(/:[A-Za-z]+/g, 'ab1')}`]))
|
||||||
|
assert.deepEqual(schreibRouten, [['POST', '/api/auftraege/ab1/bestaetigen']])
|
||||||
|
for (const [methode, pfad] of schreibRouten) {
|
||||||
|
const res = await send(methode, pfad, { ...kv(), body: { bestaetigt: true } })
|
||||||
|
assert.equal(res.status, 403, `${methode} ${pfad}`)
|
||||||
|
}
|
||||||
|
await unveraendert()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('auch der öffentliche Link bestätigt nichts, wenn der Browser eine Kundenansicht-Sitzung trägt', async () => {
|
||||||
|
const mitKennung = await send('POST', `/api/auftrag/${TOKEN}/bestaetigen`, { ...kv(), body: { bestaetigt: true } })
|
||||||
|
assert.deepEqual([mitKennung.status, mitKennung.body.code], [403, 'view_blocked'])
|
||||||
|
const ohneKennung = await send('POST', `/api/auftrag/${TOKEN}/bestaetigen`, { cookie: kv().cookie, body: { bestaetigt: true } })
|
||||||
|
assert.deepEqual([ohneKennung.status, ohneKennung.body.code], [409, 'view_replaced'])
|
||||||
|
await unveraendert()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Lesen bleibt erlaubt, kannBestaetigen ist in der Kundenansicht false; der Kunde selbst darf bestätigen', async () => {
|
||||||
|
const liste = await send('GET', '/api/auftraege', kv())
|
||||||
|
assert.equal(liste.status, 200)
|
||||||
|
assert.deepEqual(liste.body.auftraege.map((a) => [a.id, a.kannBestaetigen]), [['ab1', false]])
|
||||||
|
assert.equal((await send('GET', '/api/auftraege/ab1/pdf', kv())).status, 200)
|
||||||
|
const selbst = await send('GET', '/api/auftraege', { cookie: customerCookie('c1') })
|
||||||
|
assert.deepEqual(selbst.body.auftraege.map((a) => [a.id, a.kannBestaetigen]), [['ab1', true]])
|
||||||
|
const res = await send('POST', '/api/auftraege/ab1/bestaetigen', { cookie: customerCookie('c1'), body: { bestaetigt: true } })
|
||||||
|
assert.equal(res.status, 200)
|
||||||
|
assert.equal((await getAuftrag('ab1')).status, 'bestaetigt')
|
||||||
|
})
|
||||||
Reference in new issue
Block a user