84 lines
4.6 KiB
JavaScript
84 lines
4.6 KiB
JavaScript
import { test, after } from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
import { KEIN_PREIS, einschaltenAttrappe, htmlWurzel, ladeFunktionenModul } from './support/modulAbo.js'
|
||
|
||
// News-Pinnwand im Abo-Modell (P4 Task 4): im Zustand off nur der Platz für den Ablauf von P3 (key news), kein Preis, kein Haken, kein
|
||
// Checkout. Ohne modell === 'abo' bleibt die Buchungsseite mit Preis und Bestellknopf. wunschProjekt wählt das Projekt.
|
||
|
||
const { initNews } = await ladeFunktionenModul()
|
||
globalThis.window = { location: { hash: '#news', pathname: '/dashboard.html', search: '', href: '' }, history: { replaceState() {} } }
|
||
after(() => { delete globalThis.window })
|
||
|
||
const projekt = (id, name, state = 'off', extra = {}) => ({ projectId: id, projectName: name, features: { news: { state, ...extra } } })
|
||
async function lauf({ modell, projects = [projekt('p1', 'Muster')], dataset = {}, projectId = 'p1', einschalten } = {}) {
|
||
const calls = []
|
||
globalThis.fetch = async (url) => {
|
||
calls.push(String(url))
|
||
return { ok: true, status: 200, json: async () => ({ ...(modell ? { modell } : {}), projects, features: { news: { priceLabel: '30 €' } }, consentText: 'Alt', setupEstimate: 'meist in 1–2 Wochen', ustHinweis: 'ohne Umsatzsteuer gemäß § 19 UStG' }) }
|
||
}
|
||
const { root, stage } = htmlWurzel('#news-stage')
|
||
Object.assign(root.dataset, dataset)
|
||
await initNews(root, { projectId, einschalten })
|
||
return { root, stage, calls }
|
||
}
|
||
|
||
test('Abo: Seite ohne Preis, Haken und Checkout; der Ablauf bekommt den Platz mit key news', async () => {
|
||
const a = einschaltenAttrappe()
|
||
const { stage } = await lauf({ modell: 'abo', einschalten: a.fn })
|
||
assert.doesNotMatch(stage.innerHTML, KEIN_PREIS)
|
||
assert.doesNotMatch(stage.innerHTML, /news-consent|news-order|30 €/)
|
||
assert.deepEqual([a.aufrufe[0].key, a.aufrufe[0].projectId, a.aufrufe[0].viewAs], ['news', 'p1', false])
|
||
assert.ok(a.aufrufe[0].wurzel === stage.els['#news-einschalten'])
|
||
assert.equal(a.aufrufe.length, 1)
|
||
})
|
||
|
||
test('Abo: nach onFertig lädt die Pinnwand neu (genau einmal)', async () => {
|
||
const a = einschaltenAttrappe()
|
||
const { calls } = await lauf({ modell: 'abo', einschalten: a.fn })
|
||
a.fertig(0)
|
||
a.fertig(0)
|
||
await new Promise((r) => setImmediate(r))
|
||
assert.equal(calls.filter((u) => u === '/api/funktionen').length, 2)
|
||
})
|
||
|
||
test('Abo ohne Funktion einschalten: Satz E4 im Platz', async () => {
|
||
const { stage } = await lauf({ modell: 'abo' })
|
||
assert.match(stage.els['#news-einschalten'].textContent, /Das Einschalten ist gerade nicht verfügbar\. Bitte lade die Seite neu oder schreib uns im Chat\./)
|
||
})
|
||
|
||
test('Abo, einschalten scheitert: Satz E4 im Platz statt eines unbehandelten Fehlers', async () => {
|
||
const { stage } = await lauf({ modell: 'abo', einschalten: () => Promise.reject(new Error('kaputt')) })
|
||
await new Promise((r) => setImmediate(r))
|
||
assert.match(stage.els['#news-einschalten'].textContent, /Das Einschalten ist gerade nicht verfügbar\./)
|
||
})
|
||
|
||
test('Abo, in Einrichtung: Statuskarte mit „Eingeschaltet am“ statt „Bestellt am“, der Ablauf wird nicht gerufen', async () => {
|
||
const a = einschaltenAttrappe()
|
||
const { stage } = await lauf({ modell: 'abo', projects: [projekt('p1', 'Muster', 'setup', { orderedAt: '2026-10-16T09:00:00.000Z', ticketWoid: '100150' })], einschalten: a.fn })
|
||
assert.match(stage.innerHTML, /<dt>Eingeschaltet am<\/dt><dd>16\.10\.2026<\/dd>/)
|
||
assert.doesNotMatch(stage.innerHTML, /Bestellt am/)
|
||
assert.equal(a.aufrufe.length, 0)
|
||
})
|
||
|
||
test('Ohne modell (fehlt, „Abo“): unverändert Preis, Haken und Bestellknopf; der Ablauf wird nie gerufen', async () => {
|
||
for (const modell of [undefined, 'Abo', 'abo ']) {
|
||
const a = einschaltenAttrappe()
|
||
const { stage } = await lauf({ modell, einschalten: a.fn })
|
||
assert.match(stage.innerHTML, /<strong>30 €<\/strong>/)
|
||
assert.match(stage.innerHTML, /id="news-order" disabled>Zahlungspflichtig bestellen · 30 €</)
|
||
assert.equal(a.aufrufe.length, 0)
|
||
}
|
||
})
|
||
|
||
test('Ohne modell, in Einrichtung: weiter „Bestellt am“', async () => {
|
||
const { stage } = await lauf({ projects: [projekt('p1', 'Muster', 'setup', { orderedAt: '2026-10-16T09:00:00.000Z' })] })
|
||
assert.match(stage.innerHTML, /<dt>Bestellt am<\/dt>/)
|
||
})
|
||
|
||
test('wunschProjekt aus dem Behälter wählt das Projekt und wird entfernt', async () => {
|
||
const a = einschaltenAttrappe()
|
||
const { root } = await lauf({ modell: 'abo', projects: [projekt('p1', 'Muster'), projekt('p2', 'Muster 2')], dataset: { wunschProjekt: 'p2' }, projectId: '', einschalten: a.fn })
|
||
assert.equal(a.aufrufe[0].projectId, 'p2')
|
||
assert.equal(root.dataset.wunschProjekt, undefined)
|
||
})
|