Buchungskalender: im Abo-Modell Anfrage ohne Preis und Einschalten nach der Zusage
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
28da4180bd
commit
5f3d8f3e96
4 files changed
+122
-23
No files matched your search
@@ -0,0 +1,80 @@
|
||||
import { test } from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { h } from '../public/shop-dom.js'
|
||||
import { initBuchungen, vergissAuswahl } from '../public/buchungen.js'
|
||||
import { anfrageZeilen } from '../public/buchungen-anfrage.js'
|
||||
import { KEIN_PREIS, einschaltenAttrappe, mitDom, routen } from './support/modulAbo.js'
|
||||
|
||||
// Buchungskalender im Abo-Modell (P4 Task 6): Anfrage ohne Preis (S1), nach der Zusage der Ablauf des Einschaltens statt des Hinweises
|
||||
// „Wir melden uns bei dir“. Ohne modell === 'abo' bleibt alles wie heute.
|
||||
|
||||
const ANFRAGE = { art: 'ferienwohnung', einheiten: 2, portale: ['booking'], nachricht: '' }
|
||||
const ZUGESAGT = { status: 'angenommen', anfrage: ANFRAGE, at: '2026-10-05T10:30:00.000Z' }
|
||||
async function oeffne(fx, { kopf = {}, anfrage = null, einschalten } = {}) {
|
||||
vergissAuswahl()
|
||||
routen(fx, {
|
||||
'GET /api/funktionen': { body: { projects: [{ projectId: 'p1', projectName: 'Haus am See', features: { unterkunft: { state: 'off' } } }], unterkunft: { verfuegbar: true }, ...kopf } },
|
||||
'GET /api/unterkunft/status?projectId=p1': { body: { state: 'off', anfrage } },
|
||||
'POST /api/unterkunft/anfrage-funktion?projectId=p1': { status: 201, body: { anfrage: {} } },
|
||||
})
|
||||
const root = h('div')
|
||||
document.body.append(root)
|
||||
await initBuchungen(root, { projectId: 'p1', einschalten })
|
||||
await fx.ruhe()
|
||||
return root
|
||||
}
|
||||
|
||||
test('anfrageZeilen: Zeilen der Liste als { name, wert }, ohne Objekt leer', () => {
|
||||
assert.deepEqual(anfrageZeilen(ANFRAGE), [
|
||||
{ name: 'Art der Unterkunft', wert: 'Ferienwohnung oder Ferienhaus' },
|
||||
{ name: 'Anzahl Einheiten', wert: '2' },
|
||||
{ name: 'Portale', wert: 'Booking.com' },
|
||||
])
|
||||
assert.deepEqual(anfrageZeilen({ art: 'monteur', einheiten: 1, portale: [], nachricht: 'Hallo' }).map((z) => z.wert), ['Monteurwohnung', '1', 'keine', 'Hallo'])
|
||||
assert.deepEqual(anfrageZeilen(null), [])
|
||||
assert.deepEqual(anfrageZeilen('x'), [])
|
||||
})
|
||||
|
||||
test('Abo: Anfrageformular nennt S1, kein Preis, sendet den Körper unverändert', mitDom(async (fx) => {
|
||||
const root = await oeffne(fx, { kopf: { modell: 'abo' } })
|
||||
const text = fx.text(fx.finde(root, '.sh-erklaerung'))
|
||||
assert.match(text, /Im Wartungs-Abo enthalten\./)
|
||||
assert.match(text, /Erst nach unserer Zusage kannst du einschalten\./)
|
||||
assert.doesNotMatch(text, KEIN_PREIS)
|
||||
assert.doesNotMatch(text, /bestellen/)
|
||||
await fx.setze(fx.finde(root, '[data-feld="art"]'), 'ferienwohnung')
|
||||
await fx.setze(fx.finde(root, '[data-feld="einheiten"]'), '2')
|
||||
await fx.klick(fx.finde(root, '[data-feld="portale.booking"]'))
|
||||
await fx.klick(fx.finde(root, '[data-aktion="anfrage-senden"]'))
|
||||
assert.deepEqual(fx.fetchLog.find((x) => x.method === 'POST').body, ANFRAGE)
|
||||
}))
|
||||
|
||||
test('Abo, angenommen: Gruppe B1 und Ablauf key unterkunft; kein Haken, kein Wort „Rechnung“; onFertig lädt neu', mitDom(async (fx) => {
|
||||
const a = einschaltenAttrappe()
|
||||
const root = await oeffne(fx, { kopf: { modell: 'abo' }, anfrage: ZUGESAGT, einschalten: a.fn })
|
||||
assert.equal(a.aufrufe[0].key, 'unterkunft')
|
||||
assert.equal(a.aufrufe[0].projectId, 'p1')
|
||||
assert.equal(fx.text(fx.finde(root, '.tm-bestellen-gruppe h4')), 'Deine Anfrage')
|
||||
assert.match(fx.text(root), /Art der Unterkunft: Ferienwohnung oder Ferienhaus/)
|
||||
assert.equal(fx.alle(root, 'input[type="checkbox"]').length, 0)
|
||||
assert.doesNotMatch(fx.text(root), /Rechnung/)
|
||||
assert.doesNotMatch(fx.text(root), KEIN_PREIS)
|
||||
a.fertig(0)
|
||||
await fx.ruhe()
|
||||
assert.equal(fx.fetchLog.filter((x) => x.url === '/api/unterkunft/status?projectId=p1').length, 2)
|
||||
}))
|
||||
|
||||
test('Abo, angenommen, ohne Funktion einschalten: Fehlerkarte E4', mitDom(async (fx) => {
|
||||
const root = await oeffne(fx, { kopf: { modell: 'abo' }, anfrage: ZUGESAGT })
|
||||
assert.match(fx.text(root), /Das Einschalten ist gerade nicht verfügbar\./)
|
||||
}))
|
||||
|
||||
test('Ohne modell (fehlt, „Abo“): Formular mit „199 € einmalig“, angenommen zeigt „Wir melden uns bei dir“, der Ablauf wird nie gerufen', mitDom(async (fx) => {
|
||||
for (const modell of [undefined, 'Abo']) {
|
||||
const a = einschaltenAttrappe()
|
||||
const kopf = modell ? { modell } : {}
|
||||
assert.match(fx.text(await oeffne(fx, { kopf, einschalten: a.fn })), /199 € einmalig für den Einbau in deine Website\./)
|
||||
assert.match(fx.text(await oeffne(fx, { kopf, anfrage: ZUGESAGT, einschalten: a.fn })), /Wir melden uns bei dir mit den nächsten Schritten zur Bestellung\./)
|
||||
assert.equal(a.aufrufe.length, 0)
|
||||
}
|
||||
}))
|
||||
@@ -127,7 +127,7 @@ test('Portal: app.js und dashboard.html kennen den Reiter buchungen', () => {
|
||||
const html = lies('public/dashboard.html')
|
||||
assert.match(html, /<section class="kb-view" id="view-buchungen">[\s\S]*?<div id="buchungen-body">[\s\S]*?<\/section>/)
|
||||
assert.equal([...html.matchAll(/id="buchungen-body"/g)].length, 1)
|
||||
assert.match(lies('public/buchungen.js'), /export function initBuchungen\(root, \{ projectId \} = \{\}\)/)
|
||||
assert.match(lies('public/buchungen.js'), /export function initBuchungen\(root, \{ projectId, einschalten \} = \{\}\)/)
|
||||
})
|
||||
|
||||
test('Server: index.js hängt Mounts und Jobs ein, die Router-Dateien existieren', () => {
|
||||
|
||||
Reference in new issue
Block a user