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

110 lines
6.7 KiB
JavaScript

import { test } from 'node:test'
import assert from 'node:assert/strict'
import { h } from '../public/termine-dom.js'
import { initZeiten } from '../public/zeiten.js'
import { zeitenStatusKarte } from '../public/zeiten-bestellen.js'
import { KEIN_PREIS, einschaltenAttrappe, mitDom, routen } from './support/modulAbo.js'
// Öffnungszeiten live im Abo-Modell (P4 Task 7): Einschalten über den Ablauf von P3, kein Behalten-Weg, Abo-Ende und Abschaltung ohne Preis
// (Texte Z2, Z3, E5). Ohne modell === 'abo' bleiben Bestellseite, „Für 30 € behalten“ und „Bestellt am“.
const EDITOR = { state: 'active', daten: null, version: 0, kundenansicht: false, vorschau: null, feiertage: [], googleText: '' } // Antwort von GET /api/zeiten/p1
const feature = (state, extra = {}) => ({
state, siteKey: null, ticketWoid: null, orderedAt: null, activatedAt: null, invoiceUrl: null, disabledReason: null, disabledAt: null, loeschungAm: null,
unlockedBy: state === 'off' ? null : 'abo', aboEndeAt: null, einbau: null, ...extra,
})
const liste = (modell, state = 'off', extra = {}, angebot = {}) => ({
body: {
...(modell ? { modell } : {}),
projects: [{ projectId: 'p1', projectName: 'Website p1', liveUrl: '', features: { news: { state: 'off' }, zeiten: feature(state, extra) }, zeitenStatus: null, zeitenLeer: false }],
features: {
zeiten: {
priceLabel: '30 €',
consent: { version: 'v', knopf: 'Zahlungspflichtig bestellen · 30 €', items: [] },
leistungsbeschreibung: { version: '2026-10-05', url: '/vertragsunterlagen/zeiten-leistungsbeschreibung.html' },
},
},
ustHinweis: 'ohne Umsatzsteuer gemäß § 19 UStG',
zeiten: {
verfuegbar: true,
inklusive: true,
grund: null,
preis: '30 €',
einschalten: { consent: { version: 'v', knopf: 'Einschalten', items: [] }, leistungsbeschreibung: { version: '2026-10-05', url: '/vertragsunterlagen/zeiten-leistungsbeschreibung.html' } },
belehrung: 'Belehrung',
...angebot,
},
},
})
async function oeffne(fx, antwort, { einschalten, dataset = {} } = {}) {
routen(fx, { 'GET /api/funktionen': antwort, 'GET /api/zeiten/p1': { body: EDITOR } })
const root = h('div')
document.body.append(root)
Object.assign(root.dataset, dataset)
await initZeiten(root, { projectId: 'p1', einschalten })
await fx.ruhe()
return root
}
const ALT_ENDE = { aboEndeAt: '2026-09-01T00:00:00.000Z' }
const KEIN_ABO = { inklusive: false, grund: 'kein_abo' }
test('Abo, off: Einschalt-Seite mit key zeiten, ohne Haken, Preis und Behalten; nach onFertig die Danke-Zeile', mitDom(async (fx) => {
const a = einschaltenAttrappe()
let n = 0
const root = await oeffne(fx, () => (n === 0 ? liste('abo') : liste('abo', 'setup')), { einschalten: a.fn })
assert.deepEqual([a.aufrufe[0].key, a.aufrufe[0].projectId, a.aufrufe[0].viewAs], ['zeiten', 'p1', false])
assert.equal(fx.alle(root, 'input[type="checkbox"]').length, 0)
assert.ok(fx.finde(root, '[data-aktion="behalten"], [data-aktion="bestellen"], [data-aktion="einschalten"]') === null)
assert.doesNotMatch(fx.text(root), KEIN_PREIS)
n = 1
a.fertig(0)
await fx.ruhe()
assert.match(fx.text(fx.finde(root, '.zt-status')), /Öffnungszeiten live ist eingeschaltet\./)
}))
test('Abo, off ohne Funktion einschalten: Fehlerkarte E4', mitDom(async (fx) => {
const root = await oeffne(fx, liste('abo'))
assert.match(fx.text(root), /Das Einschalten ist gerade nicht verfügbar\. Bitte lade die Seite neu oder schreib uns im Chat\./)
}))
test('Abo: Abo-Ende in active nennt die Frist (Z2) und „Eingeschaltet am“, ohne Preis und ohne Behalten-Knopf', mitDom(async (fx) => {
const karte = zeitenStatusKarte({ projekt: { projectId: 'p1', zeitenLeer: false }, feature: { state: 'active', orderedAt: '2026-08-01T10:00:00.000Z', ...ALT_ENDE }, angebot: { ...KEIN_ABO, preis: '30 €' }, modell: 'abo' }, {})
assert.match(fx.text(karte), /Dein Wartungs-Abo ist beendet\. Öffnungszeiten live läuft noch bis 01\.10\.2026 und schaltet sich dann ab\./)
assert.match(fx.text(karte), /Eingeschaltet am\s*01\.08\.2026/)
assert.ok(fx.finde(karte, '[data-aktion="behalten"]') === null)
assert.doesNotMatch(fx.text(karte), KEIN_PREIS)
}))
test('Abo: abgeschaltet mit Daten (Z3), ohne Behalten-Knopf', mitDom(async (fx) => {
const karte = zeitenStatusKarte({ projekt: { projectId: 'p1', zeitenLeer: false }, feature: { state: 'disabled', disabledReason: 'abo_ende', loeschungAm: '2099-12-31' }, angebot: { ...KEIN_ABO, preis: '30 €' }, modell: 'abo' }, {})
assert.match(fx.text(karte), /Deine Eingaben bleiben bis 31\.12\.2099 gespeichert\. Mit einem neuen Wartungs-Abo schaltet sich Öffnungszeiten live wieder ein\./)
assert.ok(fx.finde(karte, '[data-aktion="behalten"]') === null)
assert.doesNotMatch(fx.text(karte), KEIN_PREIS)
const ohneDatum = zeitenStatusKarte({ projekt: { projectId: 'p1', zeitenLeer: false }, feature: { state: 'disabled', disabledReason: 'abo_ende' }, angebot: { ...KEIN_ABO, preis: '30 €' }, modell: 'abo' }, {})
assert.match(fx.text(ohneDatum), /Deine Eingaben bleiben gespeichert\. Mit einem neuen Wartungs-Abo schaltet sich Öffnungszeiten live wieder ein\./)
}))
test('wunschWeg „behalten“: im Abo-Modell ohne Wirkung, ohne modell die Behalten-Seite und der Knopf „Für 30 € behalten“', mitDom(async (fx) => {
const wunsch = { dataset: { wunschWeg: 'behalten' } }
const abo = await oeffne(fx, liste('abo', 'active', ALT_ENDE, KEIN_ABO), wunsch)
assert.ok(fx.finde(abo, '[data-variante="behalten"]') === null)
assert.ok(fx.finde(abo, '[data-aktion="behalten"]') === null)
assert.ok(fx.finde(abo, '.zt-status'))
assert.equal(abo.dataset.wunschWeg, undefined)
const alt = await oeffne(fx, liste(undefined, 'active', ALT_ENDE, KEIN_ABO), wunsch)
assert.ok(fx.finde(alt, '[data-variante="behalten"]'))
const karte = zeitenStatusKarte({ projekt: { projectId: 'p1', zeitenLeer: false }, feature: { state: 'active', ...ALT_ENDE }, angebot: { ...KEIN_ABO, preis: '30 €' } }, {})
assert.equal(fx.text(fx.finde(karte, '[data-aktion="behalten"]')), 'Für 30 € behalten')
}))
test('Ohne modell (fehlt, „Abo“, „abo “): Bestellseite wie bisher, „Bestellt am“, der Ablauf wird nie gerufen', mitDom(async (fx) => {
for (const modell of [undefined, 'Abo', 'abo ']) {
const a = einschaltenAttrappe()
const bestellen = await oeffne(fx, liste(modell, 'off', {}, KEIN_ABO), { einschalten: a.fn })
assert.ok(fx.finde(bestellen, '[data-aktion="bestellen"]'), String(modell))
assert.equal(a.aufrufe.length, 0)
const karte = zeitenStatusKarte({ projekt: { projectId: 'p1', zeitenLeer: false }, feature: { state: 'active', orderedAt: '2026-08-01T10:00:00.000Z' }, angebot: { inklusive: true }, modell }, {})
assert.match(fx.text(karte), /Bestellt am\s*01\.08\.2026/)
}
}))