Terminplaner TP2 C10a: Nachbesserung 1 (Abo-Hinweis vom Server, R111)
GET /api/funktionen liefert bei termine.verfuegbar ein fuenftes Feld hinweis (aboMeldung mit dem Register des Terminplaners, null bei bestellbar true). Die Kachel zeigt diesen Text maskiert an; die Browser-Kopie der Abo-Texte und der Gleichheitstest entfallen. Der Link "Zu Verträge" ist eine gemeinsame Konstante fuer Analyse und Terminplaner und erscheint bei kein_abo. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6ae0f67457
commit
52456dac76
5 files changed
+141
-63
No files matched your search
@@ -20,6 +20,7 @@ const { default: teamRoutes } = await import('../server/routes/team/index.js')
|
||||
const sf = await import('../server/services/siteFeatures.js')
|
||||
const { loeschTag } = await import('../server/services/termine/frist.js')
|
||||
const { deleteCustomerWithPortalAccess } = await import('../server/services/customerAdmin.js')
|
||||
const { aboMeldung } = await import('../server/services/featureOrder.js')
|
||||
|
||||
const app = await startTestApp({ '/api/funktionen': funktionenRoutes, '/api/team': teamRoutes })
|
||||
after(() => Promise.all([app.close(), aw.close(), st.close()]))
|
||||
@@ -165,7 +166,8 @@ test('GET /api/funktionen: termine.verfuegbar je Modus und Pilot-E-Mail; false b
|
||||
assert.equal(await verfuegbar(customerCookie('c2')), true)
|
||||
})
|
||||
|
||||
// ---- Abo-Felder der Kachel (C10a): bestellbar, grund, preis, einrichtung nur bei verfuegbar: true
|
||||
// ---- Abo-Felder der Kachel (C10a): bestellbar, grund, preis, einrichtung, hinweis nur bei verfuegbar: true
|
||||
// hinweis (R111) = aboMeldung des Registers: der Browser zeigt den Text nur an und hat keine Kopie; bei bestellbar true null
|
||||
const wartung = (patch = {}) => aw.seed('subscriptions', subscriptionDoc('sub_h', { ...wartungDoc, ...patch }))
|
||||
const angebot = (bestellbar, grund) => ({
|
||||
verfuegbar: true,
|
||||
@@ -173,6 +175,7 @@ const angebot = (bestellbar, grund) => ({
|
||||
grund,
|
||||
preis: config.features.termine.priceLabel,
|
||||
einrichtung: config.features.termine.setupEstimate,
|
||||
hinweis: bestellbar === true ? null : aboMeldung(config.features.termine, grund ?? 'unbekannt'),
|
||||
})
|
||||
|
||||
test('GET /api/funktionen: Kunde mit Wartungs-Abo => bestellbar true, grund null, Preis und Einrichtung aus dem Register', async (t) => {
|
||||
@@ -182,7 +185,38 @@ test('GET /api/funktionen: Kunde mit Wartungs-Abo => bestellbar true, grund null
|
||||
const termine = await termineAntwort()
|
||||
assert.deepEqual(termine, angebot(true, null))
|
||||
assert.ok(termine.preis && termine.einrichtung, 'das Register liefert beide Werte')
|
||||
assert.deepEqual(Object.keys(termine), ['verfuegbar', 'bestellbar', 'grund', 'preis', 'einrichtung'])
|
||||
assert.deepEqual(Object.keys(termine), ['verfuegbar', 'bestellbar', 'grund', 'preis', 'einrichtung', 'hinweis'])
|
||||
assert.equal(termine.hinweis, null, 'bestellbar: kein Hinweis (das Feld steht da, ist aber null)')
|
||||
})
|
||||
|
||||
test('GET /api/funktionen: hinweis ist der Text von aboMeldung mit dem Register des Terminplaners, je Grund', async (t) => {
|
||||
t.after(() => aw.seed('subscriptions', hostingDoc))
|
||||
termineMit('pilot', ['*'])
|
||||
const faelle = [
|
||||
['kein_abo', () => {}, 'Für den Terminplaner brauchst du ein laufendes Wartungs-Abo.'],
|
||||
['gekuendigt', () => wartung({ cancelAtPeriodEnd: true }), 'Dein Wartungs-Abo ist gekündigt. Für den Terminplaner brauchst du ein laufendes Abo.'],
|
||||
[
|
||||
'nicht_aktiv',
|
||||
() => wartung({ status: 'past_due' }),
|
||||
'Dein Wartungs-Abo ist gerade nicht aktiv (zum Beispiel wegen einer offenen Zahlung). Sobald es wieder aktiv ist, kannst du den Terminplaner bestellen.',
|
||||
],
|
||||
]
|
||||
for (const [grund, richteEin, text] of faelle) {
|
||||
aw.seed('subscriptions', hostingDoc)
|
||||
richteEin()
|
||||
const termine = await termineAntwort()
|
||||
assert.equal(termine.bestellbar, false, grund)
|
||||
assert.equal(termine.grund, grund)
|
||||
assert.equal(termine.hinweis, text, grund)
|
||||
assert.equal(termine.hinweis, aboMeldung(config.features.termine, grund), grund)
|
||||
}
|
||||
// ein Lesefehler: bestellbar null, grund null => Text zu 'unbekannt'
|
||||
aw.seed('subscriptions', hostingDoc)
|
||||
wartung()
|
||||
t.mock.method(console, 'error', () => {})
|
||||
aw.failNext({ collection: 'subscriptions', status: 500, message: 'x' })
|
||||
const unbekannt = await termineAntwort()
|
||||
assert.deepEqual([unbekannt.bestellbar, unbekannt.grund, unbekannt.hinweis], [null, null, 'Das Abo konnte gerade nicht geprüft werden.'])
|
||||
})
|
||||
|
||||
test('GET /api/funktionen: ohne Wartungs-Abo (nur Hosting, gar kein Abo, beendet) => bestellbar false, grund kein_abo', async (t) => {
|
||||
@@ -212,11 +246,15 @@ test('GET /api/funktionen: Lesefehler im Abo => bestellbar null, grund null, die
|
||||
const fehler = t.mock.method(console, 'error', () => {})
|
||||
termineMit('pilot', ['*'])
|
||||
wartung()
|
||||
// eigenes Projekt mit aktivem Terminplaner: der Test haengt nicht von den Zustaenden aus frueheren Tests ab
|
||||
aw.seed('websiteProjects', { $id: 'pt_lesefehler', customerId: 'c1', projectName: 'Lesefehler Salon' })
|
||||
aw.seed('portalFeatures', { $id: 'f_pt_lesefehler_termine', customerId: 'c1', projectId: 'pt_lesefehler', featureKey: 'termine', siteKey: 'abcdefghijklmnop', state: 'active', enabled: true })
|
||||
aw.failNext({ collection: 'subscriptions', status: 500, message: 'geheimer Appwrite-Text' })
|
||||
const res = await get('/api/funktionen', { cookie })
|
||||
assert.deepEqual(res.termine, angebot(null, null))
|
||||
for (const id of ['pt1', 'pt2']) assert.ok(res.projects.some((p) => p.projectId === id), `Projekt ${id} ist in der Liste`)
|
||||
assert.equal(featuresOf({ body: res }, 'pt1').termine.state, 'active', 'die Zustaende der Projekte bleiben')
|
||||
assert.equal(res.termine.hinweis, 'Das Abo konnte gerade nicht geprüft werden.')
|
||||
assert.ok(res.projects.some((p) => p.projectId === 'pt_lesefehler'), 'das Projekt ist in der Liste')
|
||||
assert.equal(featuresOf({ body: res }, 'pt_lesefehler').termine.state, 'active', 'die Zustaende der Projekte bleiben')
|
||||
assert.ok(!JSON.stringify(res).includes('geheimer'))
|
||||
assert.ok(fehler.mock.calls.every((aufruf) => !String(aufruf.arguments[0]).includes('geheimer')), 'auch nicht im Log')
|
||||
assert.ok(fehler.mock.calls.length >= 1, 'der Fehler steht im Log')
|
||||
|
||||
Reference in new issue
Block a user