Files
Webklar-Kundenbereich/test/kundenansichtNeuModulNews.test.js

95 lines
4.9 KiB
JavaScript
Raw Permalink 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, 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)
})
test('Abo, Kundenansicht der Mitarbeiter (window.KbView.id): der Ablauf bekommt viewAs true', async () => {
globalThis.window.KbView = { id: () => 'view1' }
try {
const a = einschaltenAttrappe()
await lauf({ modell: 'abo', einschalten: a.fn })
assert.equal(a.aufrufe[0].viewAs, true)
} finally {
delete globalThis.window.KbView
}
})