Zusammenführung von TP2-Abschluss und Webshop (origin/main cab9c33) mit Öffnungszeiten live. Beide
Funktionen bleiben vollständig: jeder Konflikt ist als Vereinigung gelöst, Reihenfolge der Funktionsschlüssel
überall news, termine, shop, zeiten.
Konfliktdateien (28): public/app.js, dashboard.html, funktionen.js, widerrufen.html; scripts/stripe-products.mjs;
server/config.js, index.js, middleware/kundenansichtGuard.js, routes/abo.js, routes/admin/funktionenAdmin.js,
routes/funktionen.js, services/customerAdmin.js, customerViewLog.js, featureRegistry.js, retention.js,
siteFeatures.js, stripeBilling.js; test/customerViewLog, featureFreischaltung, featureRegistry, funktionenRoutes,
funktionenTermine, kundenansichtGuard, mailTemplates, publicForms, siteFeatures, stripeProductsScript (je
.test.js) und test/support/schema.js.
Entscheidungen: Mailvorlagen G01–G15, K01–K30, T01–T21 lückenlos (K24–K26 Webshop, K27–K30 Öffnungszeiten);
Stripe-Katalog mit shopSetup und zeitenSetup; Widerruf kennt shop und zeiten; ABO_FUNKTIONEN bleibt analyse
und termine (kein zeiten); activate() schreibt die Zeiten-Felder nur über extra; kein Halter von
feature-activate:<id> ruft disable() auf; die Aufbewahrungs-Löschung löscht Zeiten-Daten vor dem Abschalten und
hält den Kunden bei einem Fehler (held); die Admin-Antwort trägt ersatzTicket und warnung; Hash-Routen webshop
und zeiten, Ansichten view-webshop und view-zeiten; assertOwnProject behält die Meldung von main.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.6 KiB
JavaScript
69 lines
2.6 KiB
JavaScript
import { test, after } from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
import { startAppwriteMock } from './support/appwriteMock.js'
|
||
import { startFakeStripe } from './support/fakeStripe.js'
|
||
import { useTestEnv } from './support/testEnv.js'
|
||
|
||
// scripts/stripe-products.mjs: der Import darf weder main() starten (kein Stripe-Aufruf, kein process.exit) noch etwas anlegen;
|
||
// "--anlegen" macht der Inhaber im Livegang (Block G, Schritt 4).
|
||
const aw = await startAppwriteMock()
|
||
const st = await startFakeStripe()
|
||
after(() => Promise.all([aw.close(), st.close()]))
|
||
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
|
||
const { config } = await import('../server/config.js')
|
||
|
||
const realExit = process.exit
|
||
let exitCalls = 0
|
||
process.exit = () => {
|
||
exitCalls += 1
|
||
}
|
||
let script
|
||
try {
|
||
script = await import('../scripts/stripe-products.mjs')
|
||
// main() liefe asynchron an: einen Moment warten, damit ein versehentlicher Start sichtbar wird
|
||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||
} finally {
|
||
process.exit = realExit
|
||
}
|
||
|
||
test('Import startet main() nicht: kein Stripe-Aufruf, kein process.exit', () => {
|
||
assert.equal(exitCalls, 0)
|
||
assert.equal(st.calls.length, 0)
|
||
})
|
||
|
||
test('KEYS enthaelt die Katalogschluessel der Einrichtungen (News, Terminplaner, Webshop, Oeffnungszeiten live)', () => {
|
||
assert.deepEqual(script.KEYS, ['wartung', 'hosting', 'mailStorage', 'newsSetup', 'termineSetup', 'shopSetup', 'zeitenSetup'])
|
||
})
|
||
|
||
test('catalogEntry liefert die Katalogeintraege aus der Konfiguration', () => {
|
||
assert.equal(script.catalogEntry('termineSetup'), config.termineSetup)
|
||
assert.equal(script.catalogEntry('shopSetup'), config.shopSetup)
|
||
assert.equal(script.catalogEntry('zeitenSetup'), config.zeitenSetup)
|
||
assert.equal(script.catalogEntry('newsSetup'), config.newsSetup)
|
||
assert.equal(script.catalogEntry('mailStorage'), config.mailStorage)
|
||
assert.equal(script.catalogEntry('wartung'), config.products.wartung)
|
||
for (const key of script.KEYS) assert.ok(script.catalogEntry(key)?.lookupKey, `${key} hat einen lookupKey`)
|
||
})
|
||
|
||
test('config.shopSetup: Festwerte', () => {
|
||
assert.deepEqual(config.shopSetup, {
|
||
key: 'shopSetup',
|
||
name: 'Webshop – Einrichtung',
|
||
amountCents: 29900,
|
||
lookupKey: 'webklar_shop_einrichtung_29900',
|
||
oneTime: true,
|
||
priceNickname: 'Webshop-Einrichtung 299 €',
|
||
})
|
||
})
|
||
|
||
test('config.termineSetup: Festwerte', () => {
|
||
assert.deepEqual(config.termineSetup, {
|
||
key: 'termineSetup',
|
||
name: 'Terminplaner – Einrichtung',
|
||
amountCents: 14900,
|
||
lookupKey: 'webklar_termine_einrichtung_14900',
|
||
oneTime: true,
|
||
priceNickname: 'Terminplaner-Einrichtung 149 €',
|
||
})
|
||
})
|