Files
Webklar-Kundenbereich/test/kundenansichtNews.test.js
T

96 lines
4.6 KiB
JavaScript

import { test, after } 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 sharp from 'sharp'
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: News-Aenderungen eines Mitarbeiters landen mit Titel im Protokoll, die des Kunden nicht
process.env.NEWS_UPLOAD_DIR = mkdtempSync(path.join(os.tmpdir(), 'kundenansicht-news-'))
const aw = await startAppwriteMock({
schema: {
customerViewLog: schemaKeys('customerViewLog'),
portalFeatures: schemaKeys('portalFeatures'),
newsPosts: schemaKeys('newsPosts'),
},
})
const st = await startFakeStripe()
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
const { startTestApp } = await import('./support/testApp.js')
const { seedFixtures, customerCookie, kundenansichtCookie } = await import('./support/fixtures.js')
const { kundenansichtGuard } = await import('../server/middleware/kundenansichtGuard.js')
const { default: newsRoutes } = await import('../server/routes/news.js')
const app = await startTestApp({ '/': kundenansichtGuard, '/api/news': newsRoutes })
after(() => Promise.all([app.close(), aw.close(), st.close()]))
seedFixtures(aw)
aw.seed('websiteProjects', { $id: 'p1', customerId: 'c1', projectName: 'Bäckerei' })
aw.seed('portalFeatures', { $id: 'f_p1_news', customerId: 'c1', projectId: 'p1', featureKey: 'news', state: 'active', enabled: true, siteKey: 'abcdefghijklmnop' })
const VIEW = 'a'.repeat(32)
const staff = { cookie: kundenansichtCookie(), headers: { 'x-kundenansicht': VIEW } }
const note = { projectId: 'p1', type: 'note', title: 'Hallo', text: 'Wir haben offen', paper: 'sun', duration: '1m' }
const call = async (method, url, { cookie, headers = {}, body } = {}) => {
const raw = Buffer.isBuffer(body)
const res = await fetch(app.url + url, {
method,
headers: { ...(cookie ? { cookie } : {}), ...(body !== undefined && !raw ? { 'content-type': 'application/json' } : {}), ...headers },
body: body === undefined ? undefined : raw ? body : JSON.stringify(body),
})
const text = await res.text()
return { status: res.status, body: text ? JSON.parse(text) : null }
}
const logOf = (customerId) => [...aw.docs('customerViewLog').values()].filter((d) => d.customerId === customerId)
const png = () => sharp({ create: { width: 40, height: 30, channels: 3, background: '#c33' } }).png().toBuffer()
test('anlegen, aendern, Foto, loeschen in der Kundenansicht -> vier Protokolleintraege', async () => {
const before = logOf('c1').length
const created = await call('POST', '/api/news', { ...staff, body: note })
assert.equal(created.status, 201)
const id = created.body.$id
const patched = await call('PATCH', `/api/news/${id}`, { ...staff, body: { ...note, title: 'Neu' } })
assert.equal(patched.status, 200)
const image = await call('POST', '/api/news/image?projectId=p1', {
...staff,
headers: { ...staff.headers, 'content-type': 'application/octet-stream' },
body: await png(),
})
assert.equal(image.status, 201)
const removed = await call('DELETE', `/api/news/${id}?projectId=p1`, staff)
assert.equal(removed.status, 204)
const entries = logOf('c1').slice(before)
assert.deepEqual(entries.map((e) => [e.action, e.detail]), [
['news_angelegt', 'Hallo'],
['news_geaendert', 'Neu'],
['news_bild', ''],
['news_geloescht', 'Neu'],
])
for (const e of entries) assert.deepEqual([e.staffName, e.staffUserId], ['Andrej', 'u_staff2'])
})
test('ohne Titel: Detail sind die ersten 60 Zeichen des Textes', async () => {
const before = logOf('c1').length
const text = 'Heute frische Brötchen bis 18 Uhr und morgen geschlossen wegen Inventur, danke!'
const res = await call('POST', '/api/news', { ...staff, body: { ...note, title: '', text } })
assert.equal(res.status, 201)
assert.equal(logOf('c1').slice(before)[0].detail, text.slice(0, 60))
})
test('Kunde selbst schreibt -> kein Protokolleintrag', async () => {
const before = logOf('c1').length
const res = await call('POST', '/api/news', { cookie: customerCookie('c1'), body: note })
assert.equal(res.status, 201)
assert.equal(logOf('c1').length, before)
})
test('Protokoll scheitert -> News-Aktion trotzdem 201', async (t) => {
t.mock.method(console, 'warn', () => {})
aw.failNext({ collection: 'customerViewLog', method: 'POST', status: 500, message: 'kaputt' })
const res = await call('POST', '/api/news', { ...staff, body: note })
assert.equal(res.status, 201)
})