96 lines
4.6 KiB
JavaScript
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)
|
|
})
|