Buchungskalender: Stornobedingungen je Unterkunft, Zustimmung und Bestellstatus
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
efeb99e214
commit
05006f1480
5 files changed
+123
-29
No files matched your search
@@ -470,7 +470,8 @@ test('Kalender: vergangene Tage lassen sich nicht sperren', mit(ukServer(), asyn
|
||||
|
||||
/* ===================================================== Task 14: Rechnungen, Einstellungen, Anfrage ===================================================== */
|
||||
const { render: renderRechnungen } = await import('../public/buchungen-tab-rechnungen.js')
|
||||
const { render: renderEinstellungen, STORNO_MUSTER, STORNO_HINWEIS, AUFTRAG_TEXT } = await import('../public/buchungen-tab-einstellungen.js')
|
||||
const { STORNO_MUSTER, STORNO_HINWEIS } = await import('../public/buchungen-preise.js')
|
||||
const { render: renderEinstellungen, AUFTRAG_TEXT, AUFTRAG_WIDERRUF } = await import('../public/buchungen-tab-einstellungen.js')
|
||||
const { renderAnfrageFormular, anfrageKarte } = await import('../public/buchungen-anfrage.js')
|
||||
const { initBuchungen, vergissAuswahl } = await import('../public/buchungen.js')
|
||||
|
||||
@@ -482,7 +483,7 @@ const zeigeMit = async (fx, modul, ctxExtra = {}) => {
|
||||
await fx.ruhe()
|
||||
return { panel, ctx }
|
||||
}
|
||||
const ES = { firma: 'Haus am See', inhaber: 'Mimi M.', strasse: 'Seeweg 1', plz: '78532', ort: 'Tuttlingen', email: 'mimi@example.com', telefon: '', steuernummer: '12/345/67890', ustId: '', iban: '', bic: '', bank: '', rechnungsPraefix: 'RE', akzentfarbe: '#336699', onlineZahlung: false, rechnungAuftrag: true, stornobedingungen: '' }
|
||||
const ES = { firma: 'Haus am See', inhaber: 'Mimi M.', strasse: 'Seeweg 1', plz: '78532', ort: 'Tuttlingen', email: 'mimi@example.com', telefon: '', steuernummer: '12/345/67890', ustId: '', iban: '', bic: '', bank: '', rechnungsPraefix: 'RE', akzentfarbe: '#336699', onlineZahlung: false, rechnungAuftrag: true }
|
||||
const esServer = (o = {}, antwort = {}) => server({ 'GET /api/unterkunft/einstellungen': () => ({ body: { einstellungen: ES, stripe: { status: 'keins', vorhandenesShopKonto: false }, rechnungenVorhanden: false, ...antwort } }), 'PUT /api/unterkunft/einstellungen': () => ({ body: {} }), ...o })
|
||||
|
||||
test('Rechnungen: Liste mit PDF-Link, Art und Betrag; Fremdtext nur als Text', mit(server({
|
||||
@@ -561,18 +562,43 @@ test('Einstellungen: Präfix prüfen; gesperrt mit Hinweis, sobald Rechnungen ex
|
||||
})()
|
||||
})
|
||||
|
||||
test('Einstellungen: Mustertext übernehmen füllt die Stornobedingungen, Hinweis „keine Rechtsberatung“', mit(esServer(), async (fx) => {
|
||||
test('Einstellungen: keine Stornobedingungen mehr; IBAN maxlength 34', mit(esServer(), async (fx) => {
|
||||
const { panel } = await zeigeMit(fx, renderEinstellungen)
|
||||
const t = fx.finde(panel, '[data-feld="stornobedingungen"]')
|
||||
assert.equal(t.value, '')
|
||||
assert.match(fx.text(t.parentNode), new RegExp(STORNO_HINWEIS.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')))
|
||||
assert.equal(fx.finde(panel, '[data-feld="stornobedingungen"]'), null)
|
||||
assert.equal(fx.finde(panel, '[data-feld="iban"]').getAttribute('maxlength'), '34')
|
||||
await fx.klick(fx.finde(panel, '[data-aktion="einstellungen-speichern"]'))
|
||||
await fx.ruhe()
|
||||
assert.equal('stornobedingungen' in posts(fx)[0].body, false)
|
||||
}))
|
||||
|
||||
test('Preis-Editor: Mustertext übernehmen füllt nur das Feld (kein Speichern), Hinweis „keine Rechtsberatung“', mit(ukServer(), async (fx) => {
|
||||
const panel = await preisEditor(fx)
|
||||
const t = fx.finde(panel, '#bk-p-storno')
|
||||
assert.match(fx.text(fx.finde(panel, '[data-hinweis="storno-muster"]')), /Vorlage – bitte an deine Bedingungen anpassen, keine Rechtsberatung\./)
|
||||
assert.equal(STORNO_HINWEIS, 'Vorlage – bitte an deine Bedingungen anpassen, keine Rechtsberatung.')
|
||||
const vorher = posts(fx).length
|
||||
await fx.klick(fx.finde(panel, '[data-aktion="storno-muster"]'))
|
||||
assert.equal(t.value, STORNO_MUSTER)
|
||||
assert.match(STORNO_MUSTER, /^Stornierung bis 14 Tage vor Anreise: kostenlos\./)
|
||||
assert.match(STORNO_MUSTER, /Maßgeblich ist der Eingang bei uns\.$/)
|
||||
assert.equal(posts(fx).length, vorher)
|
||||
}))
|
||||
|
||||
test('Einstellungen: Zustimmung zurückziehen fragt nach; Abbrechen behält, Ja sendet rechnungAuftrag:false', mit(esServer(), async (fx) => {
|
||||
const { panel } = await zeigeMit(fx, renderEinstellungen)
|
||||
const box = fx.finde(panel, '[data-feld="rechnungAuftrag"]')
|
||||
await fx.klick(box)
|
||||
assert.ok(box.checked)
|
||||
assert.match(fx.text(panel), new RegExp(AUFTRAG_WIDERRUF.slice(0, 50)))
|
||||
await fx.klick(fx.finde(panel, '[data-aktion="widerruf-nein"]'))
|
||||
assert.ok(box.checked)
|
||||
assert.equal(fx.finde(panel, '[data-aktion="widerruf-ja"]'), null)
|
||||
await fx.klick(box)
|
||||
await fx.klick(fx.finde(panel, '[data-aktion="widerruf-ja"]'))
|
||||
assert.equal(box.checked, false)
|
||||
await fx.klick(fx.finde(panel, '[data-aktion="einstellungen-speichern"]'))
|
||||
await fx.ruhe()
|
||||
assert.equal(posts(fx)[0].body.stornobedingungen, STORNO_MUSTER)
|
||||
assert.equal(posts(fx)[0].body.rechnungAuftrag, false)
|
||||
}))
|
||||
|
||||
test('Einstellungen: Auftrag zur Rechnungsstellung – ohne Haken Hinweis, mit Haken weg und rechnungAuftrag im PUT', mit(esServer({}, { einstellungen: { ...ES, rechnungAuftrag: false } }), async (fx) => {
|
||||
@@ -708,3 +734,49 @@ test('Ansicht #buchungen: Zustand off zeigt das Anfrageformular, Projekt vom Wun
|
||||
})()
|
||||
vergissAuswahl()
|
||||
})
|
||||
|
||||
test('Ansicht #buchungen: Zustand ordered zeigt „Zahlung offen“ mit Zahlung fortsetzen (Checkout unterkunft)', async () => {
|
||||
vergissAuswahl()
|
||||
await mit((a) => {
|
||||
if (a.url === '/api/funktionen') return { body: { unterkunft: { verfuegbar: true }, projects: [{ projectId: 'p1', projectName: 'A', features: { unterkunft: { state: 'ordered' } } }] } }
|
||||
if (a.url.startsWith('/api/unterkunft/status')) return { body: { state: 'ordered' } }
|
||||
if (a.url === '/api/funktionen/unterkunft/checkout') return { status: 409, body: { error: 'Bitte stimme zu.', code: 'andere' } }
|
||||
return { body: {} }
|
||||
}, async (fx) => {
|
||||
const root = h('div')
|
||||
fx.document.body.append(root)
|
||||
await initBuchungen(root)
|
||||
await fx.ruhe()
|
||||
assert.match(fx.text(root), /Zahlung offen/)
|
||||
await fx.klick(fx.finde(root, '[data-aktion="fortsetzen"]'))
|
||||
await fx.ruhe()
|
||||
assert.ok(posts(fx).some((a) => a.url === '/api/funktionen/unterkunft/checkout'))
|
||||
})()
|
||||
vergissAuswahl()
|
||||
})
|
||||
|
||||
test('Anfrageformular: 409 lädt die Ansicht neu, die Meldung bleibt sichtbar; Projektwechsel setzt „neue Anfrage“ zurück', async () => {
|
||||
vergissAuswahl()
|
||||
let status = { state: 'off', anfrage: { status: 'abgelehnt', begruendung: 'Nein' } }
|
||||
await mit((a) => {
|
||||
if (a.url === '/api/funktionen') return { body: { unterkunft: { verfuegbar: true }, projects: [{ projectId: 'p1', projectName: 'A', features: { unterkunft: { state: 'off' } } }, { projectId: 'p2', projectName: 'B', features: { unterkunft: { state: 'off' } } }] } }
|
||||
if (a.url.startsWith('/api/unterkunft/status')) return { body: status }
|
||||
if (a.method === 'POST') { status = { state: 'off', anfrage: { status: 'offen', anfrage: {} } }; return { status: 409, body: { fehler: 'anfrage_laeuft' } } }
|
||||
return { body: {} }
|
||||
}, async (fx) => {
|
||||
const root = h('div')
|
||||
fx.document.body.append(root)
|
||||
await initBuchungen(root)
|
||||
await fx.ruhe()
|
||||
await fx.klick(fx.finde(root, '[data-aktion="neue-anfrage"]'))
|
||||
await fx.klick(fx.finde(root, '[data-aktion="anfrage-senden"]'))
|
||||
await fx.ruhe()
|
||||
assert.ok(fx.finde(root, '[data-anfrage="offen"]'))
|
||||
assert.match(fx.text(fx.finde(root, '.sh-meldung')), /nicht geklappt/)
|
||||
status = { state: 'off', anfrage: { status: 'abgelehnt', begruendung: 'Nein' } }
|
||||
await fx.setze(fx.finde(root, '#buchungen-project'), 'p2')
|
||||
await fx.ruhe()
|
||||
assert.ok(fx.finde(root, '[data-anfrage="abgelehnt"]'))
|
||||
})()
|
||||
vergissAuswahl()
|
||||
})
|
||||
Reference in new issue
Block a user