Files
tickte-system/tests/unit/auftraegeAnsicht.test.mjs
T

145 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import test from 'node:test'
import assert from 'node:assert/strict'
import { loadModule } from './load.mjs'
const { KONTEN_FEHLER, AUFTRAEGE_FEHLER, ladeAuftraegeAnsicht, ansichtsZustand } = await loadModule('src/lib/auftraegeAnsicht.js')
// Antwort von getProjektkonten (V5) mit den Feldern, die die Ansicht braucht
const konten = (extra = {}) => ({
auftraegeAktiv: false,
kunde: { id: 'k1', name: 'Anelia Wolf', kundenart: 'privat' },
konten: [{ projektId: 'p1', name: 'Website' }],
ohneProjekt: { berechnetCents: 5000, bezahltCents: 0, anzahl: 1 },
stripeOk: true,
...extra,
})
const OHNE_PROJEKT_LEER = { berechnetCents: 0, bezahltCents: 0, anzahl: 0 }
// Attrappe für getProjektkonten und listAuftraege: gibt Werte zurück, wirft Fehler und merkt sich die Aufrufe
function fakeApi({ projektkonten, auftraege } = {}) {
const calls = []
const antwort = (wert) => {
if (wert instanceof Error) throw wert
return wert
}
return {
calls,
getProjektkonten: async (id) => { calls.push(['konten', id]); return antwort(projektkonten) },
listAuftraege: async (id) => { calls.push(['auftraege', id]); return antwort(auftraege) },
}
}
test('Schalter aus: die Aufträge werden gar nicht erst abgerufen', async () => {
const api = fakeApi({ projektkonten: konten({ auftraegeAktiv: false }), auftraege: new Error('404 darf nie ankommen') })
const result = await ladeAuftraegeAnsicht('k1', api)
assert.deepEqual(api.calls, [['konten', 'k1']])
assert.equal(result.konten.auftraegeAktiv, false)
assert.equal(result.auftraege, null)
assert.equal(result.auftraegeFehler, '')
// ein fehlendes Feld gilt wie „aus“, nur true schaltet an; eine Antwort ohne Objekt wird zu {}
const fehlt = fakeApi({ projektkonten: { konten: [] } })
assert.equal((await ladeAuftraegeAnsicht('k1', fehlt)).auftraege, null)
assert.deepEqual(fehlt.calls, [['konten', 'k1']])
const nichts = await ladeAuftraegeAnsicht('k1', fakeApi({ projektkonten: null }))
assert.deepEqual(nichts, { konten: {}, auftraege: null, auftraegeFehler: '' })
})
test('Schalter an: erst die Projektkonten, dann die Aufträge des Kunden', async () => {
const liste = [{ id: 'a1', nummer: 'AB-2026-0001', status: 'versendet' }]
const api = fakeApi({ projektkonten: konten({ auftraegeAktiv: true }), auftraege: { auftraege: liste } })
const result = await ladeAuftraegeAnsicht('k1', api)
assert.deepEqual(api.calls, [['konten', 'k1'], ['auftraege', 'k1']])
assert.deepEqual(result.auftraege, liste)
assert.equal(result.auftraegeFehler, '')
// eine Antwort ohne Liste gibt eine leere Liste statt eines Absturzes
const leer = await ladeAuftraegeAnsicht('k1', fakeApi({ projektkonten: konten({ auftraegeAktiv: true }), auftraege: {} }))
assert.deepEqual(leer.auftraege, [])
})
test('Aufträge scheitern allein: die Projektkonten bleiben, der Fehler steht eigens da', async () => {
const api = fakeApi({
projektkonten: konten({ auftraegeAktiv: true }),
auftraege: Object.assign(new Error('Interner Fehler.'), { status: 500 }),
})
const result = await ladeAuftraegeAnsicht('k1', api)
assert.equal(result.konten.konten.length, 1)
assert.equal(result.auftraege, null)
assert.equal(result.auftraegeFehler, 'Interner Fehler.')
const ohneText = await ladeAuftraegeAnsicht('k1', fakeApi({ projektkonten: konten({ auftraegeAktiv: true }), auftraege: new Error('') }))
assert.equal(ohneText.auftraegeFehler, AUFTRAEGE_FEHLER)
assert.equal(AUFTRAEGE_FEHLER, 'Die Aufträge konnten nicht geladen werden.')
})
test('Projektkonten scheitern: der Fehler geht weiter, die Aufträge werden nicht abgerufen', async () => {
const fehler = Object.assign(new Error('Interner Fehler.'), { status: 500 })
const api = fakeApi({ projektkonten: fehler, auftraege: { auftraege: [] } })
await assert.rejects(ladeAuftraegeAnsicht('k1', api), (e) => e === fehler)
assert.deepEqual(api.calls, [['konten', 'k1']])
})
test('ansichtsZustand: vor der ersten Antwort „laden“, nach einem Fehler „fehler“ mit der Meldung', () => {
const laden = ansichtsZustand({ data: null, error: '' })
assert.equal(laden.projekteStatus, 'laden')
assert.equal(laden.auftraegeStatus, 'aus') // der Schalter ist noch unbekannt: kein Abschnitt, kein Flackern
assert.deepEqual(laden.konten, [])
assert.equal(ansichtsZustand().projekteStatus, 'laden')
const fehler = ansichtsZustand({ data: null, error: KONTEN_FEHLER })
assert.equal(fehler.projekteStatus, 'fehler')
assert.equal(fehler.fehler, KONTEN_FEHLER)
assert.equal(fehler.auftraegeStatus, 'aus') // ohne Projektkonten kein Schalter, also auch keine Aufträge
assert.equal(KONTEN_FEHLER, 'Die Projektübersicht konnte nicht geladen werden.')
})
test('ansichtsZustand: Schalter aus – Projekte bereit, kein Aufträge-Abschnitt', () => {
const z = ansichtsZustand({ data: { konten: konten({ auftraegeAktiv: false }), auftraege: null, auftraegeFehler: '' }, error: '' })
assert.equal(z.projekteStatus, 'bereit')
assert.equal(z.auftraegeAktiv, false)
assert.equal(z.auftraegeStatus, 'aus')
assert.equal(z.konten.length, 1)
assert.deepEqual(z.ohneProjekt, { berechnetCents: 5000, bezahltCents: 0, anzahl: 1 })
assert.equal(z.stripeOk, true)
assert.deepEqual(z.kunde, { id: 'k1', name: 'Anelia Wolf', kundenart: 'privat' })
assert.equal(z.nachladeFehler, '')
})
test('ansichtsZustand: Schalter an – Aufträge bereit oder mit eigenem Fehler, die Projekte bleiben', () => {
const liste = [{ id: 'a1' }]
const bereit = ansichtsZustand({ data: { konten: konten({ auftraegeAktiv: true }), auftraege: liste, auftraegeFehler: '' }, error: '' })
assert.equal(bereit.auftraegeAktiv, true)
assert.equal(bereit.auftraegeStatus, 'bereit')
assert.deepEqual(bereit.auftraege, liste)
const kaputt = ansichtsZustand({
data: { konten: konten({ auftraegeAktiv: true }), auftraege: null, auftraegeFehler: 'Interner Fehler.' },
error: '',
})
assert.equal(kaputt.projekteStatus, 'bereit')
assert.equal(kaputt.auftraegeStatus, 'fehler')
assert.equal(kaputt.auftraegeFehler, 'Interner Fehler.')
assert.deepEqual(kaputt.auftraege, [])
})
test('ansichtsZustand: Neuladen scheitert – die alten Daten bleiben, die Meldung steht daneben', () => {
const data = { konten: konten({ auftraegeAktiv: true }), auftraege: [{ id: 'a1' }], auftraegeFehler: '' }
const z = ansichtsZustand({ data, error: 'Das Kundenportal ist gerade nicht erreichbar.' })
assert.equal(z.projekteStatus, 'bereit')
assert.equal(z.fehler, '')
assert.equal(z.nachladeFehler, 'Das Kundenportal ist gerade nicht erreichbar.')
assert.equal(z.konten.length, 1)
assert.equal(z.auftraegeStatus, 'bereit')
assert.equal(z.auftraege.length, 1)
})
test('ansichtsZustand: unvollständige Antworten brechen die Ansicht nicht', () => {
for (const data of [{}, { konten: null }, { konten: {} }, { konten: { konten: 'x', ohneProjekt: 5, kunde: 'k' } }]) {
const z = ansichtsZustand({ data, error: '' })
assert.equal(z.projekteStatus, 'bereit')
assert.deepEqual(z.konten, [])
assert.deepEqual(z.ohneProjekt, OHNE_PROJEKT_LEER)
assert.equal(z.stripeOk, true)
assert.equal(z.kunde, null)
assert.equal(z.auftraegeAktiv, false)
assert.equal(z.auftraegeStatus, 'aus')
}
assert.equal(ansichtsZustand({ data: { konten: konten({ stripeOk: false }) }, error: '' }).stripeOk, false)
})