Öffnungszeiten: Abo-Abgleich mit 30 Tagen Frist
gleicheZeitenAboAb(now) koppelt die im Wartungs-Abo enthaltenen Zeiten (unlockedBy abo) an das Abo (Spec 5, Z11): Abo-Ende erkennen (aboEndeAt, K26), nach 30 Berliner Kalendertagen abschalten (abo_ende, K27, Ersatz-Ticket), bei Rückkehr des Abos wieder einschalten (Neubau nach dem Abschalten, K24 wieder), 30 Tage nach dem Abschalten Daten löschen und state off. Lesefehler beim Abo: Kunde überspringen, nie abschalten oder löschen. R25: activate() leert aboEndeAt und behaltenSessionId; starteBehalten lehnt bei laufendem Wartungs-Abo mit 409 ab (Lesefehler 503). R17: k24Mail mit einbau null und wieder schaltet beide Einbau-Blöcke ab, K24 bekommt dafür den Block weiter um den Kasten "Wie geht es weiter?". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
53253f0451
commit
efc6dcf332
8 files changed
+1285
-10
No files matched your search
@@ -31,7 +31,7 @@ const st = await startFakeStripe()
|
||||
useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url })
|
||||
const { config } = await import('../server/config.js')
|
||||
const { startTestApp, post, postWebhook } = await import('./support/testApp.js')
|
||||
const { customerCookie, kundenansichtCookie, seedFixtures } = await import('./support/fixtures.js')
|
||||
const { customerCookie, kundenansichtCookie, seedFixtures, subscriptionDoc, wartungDoc } = await import('./support/fixtures.js')
|
||||
const { deleteDocument } = await import('../server/services/appwriteAdmin.js')
|
||||
const { withLocks } = await import('../server/services/keyedLock.js')
|
||||
const { setMailTransportForTests } = await import('../server/services/mailer.js')
|
||||
@@ -254,6 +254,48 @@ test('Behalten nur nach Abo-Ende, sonst 409', async () => {
|
||||
}
|
||||
})
|
||||
|
||||
test('Läuft das Wartungs-Abo wieder, ist Behalten gesperrt (409, die Funktion ist enthalten); Lesefehler beim Abo ⇒ 503; beides ohne Spur (R25)', async () => {
|
||||
const wartungLaeuft = (over = {}) => aw.seed('subscriptions', subscriptionDoc('sub_h', { ...wartungDoc, customerId: 'c1', status: 'active', ...over }))
|
||||
const LAEUFT = 'Dein Wartungs-Abo läuft wieder – Öffnungszeiten live ist darin enthalten.'
|
||||
|
||||
// aktiv mit Abo-Ende, die Zahlung hat schon begonnen (offene Sitzung): kehrt das Abo zurück, gibt es auch die alte Seite nicht mehr heraus
|
||||
seedeZeiten()
|
||||
const sessionId = await starteBehalten()
|
||||
const davor = spuren()
|
||||
wartungLaeuft()
|
||||
const res = await behalten(koerper())
|
||||
assert.equal(res.status, 409, JSON.stringify(res.body))
|
||||
assert.equal(res.body.error, LAEUFT)
|
||||
assert.equal(res.body.url, undefined)
|
||||
assert.deepEqual(spuren(), davor, 'keine neue Sitzung, kein Nachweis')
|
||||
assert.equal(zeitenDoc().behaltenSessionId, sessionId)
|
||||
|
||||
// eine vorgemerkte Kündigung zählt als laufend (bis zum Periodenende)
|
||||
wartungLaeuft({ cancelAtPeriodEnd: true })
|
||||
assert.equal((await behalten(koerper())).status, 409)
|
||||
|
||||
// abgeschaltet nach dem Abo-Ende, Eingaben noch da: ebenso
|
||||
for (const id of [...aw.docs('portalFeatures').keys()]) await deleteDocument('portalFeatures', id)
|
||||
seedeAbgeschaltet()
|
||||
await mitZeiten()
|
||||
const aus = await behalten(koerper())
|
||||
assert.equal(aus.status, 409)
|
||||
assert.equal(aus.body.error, LAEUFT)
|
||||
|
||||
// Abo-Lage nicht lesbar: fail-closed
|
||||
aw.failNext({ collection: 'subscriptions', method: 'GET', status: 500, message: 'Appwrite down' })
|
||||
const kaputt = await behalten(koerper())
|
||||
assert.equal(kaputt.status, 503)
|
||||
assert.match(kaputt.body.error, /nicht prüfbar/)
|
||||
assert.equal(JSON.stringify(kaputt.body).includes('Appwrite'), false)
|
||||
|
||||
// ohne laufendes Wartungs-Abo (Hosting, beendet) geht es weiter wie gehabt
|
||||
aw.seed('subscriptions', subscriptionDoc('sub_h', { ...wartungDoc, customerId: 'c1', status: 'canceled', endedAt: ABO_ENDE }))
|
||||
const frei = await behalten(koerper())
|
||||
assert.equal(frei.status, 200, JSON.stringify(frei.body))
|
||||
assert.equal(sessionAufrufe().length, 2, 'die erste Sitzung und diese; die gesperrten Versuche legten keine an')
|
||||
})
|
||||
|
||||
test('Vorprüfungen wie bei der Bestellung: Kundenansicht 403, gleiche Zustimmung (beide Haken), Projekt, Schalter, Unterlagen; alles ohne Spur', async () => {
|
||||
seedeZeiten()
|
||||
// Kundenansicht (Mitarbeiter bestellen nicht fuer den Kunden)
|
||||
|
||||
Reference in new issue
Block a user