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' // E-Fix M9: featureView nennt die Löschfrist auch für News (30 Tage), Webshop und Buchungskalender (90 Tage), wenn die Funktion im Abo-Modell mit dem Abo // endete (disabledReason abo_ende): derselbe Tag wie in K39 (disabledAt plus loeschFristTage) und in den Löschjobs. const aw = await startAppwriteMock({ schema: {} }) const st = await startFakeStripe() useTestEnv({ appwriteUrl: aw.url, stripeUrl: st.url }) after(() => Promise.all([aw.close(), st.close()])) const { featureView } = await import('../server/services/siteFeatures.js') const { loeschFristTage } = await import('../server/services/aboFunktionenMails.js') const BERLIN_TAG = new Intl.DateTimeFormat('en-CA', { timeZone: 'Europe/Berlin', year: 'numeric', month: '2-digit', day: '2-digit' }) const tagNach = (iso, tage) => BERLIN_TAG.format(new Date(Date.parse(iso) + tage * 24 * 60 * 60 * 1000)) const DISABLED_AT = '2026-10-04T23:30:00.000Z' // spät am Abend (UTC): der Berliner Tag liegt einen Tag später const aus = (featureKey, over = {}) => ({ featureKey, state: 'disabled', disabledReason: 'abo_ende', disabledAt: DISABLED_AT, unlockedBy: 'abo', einrichtungAbrechnung: 'abo', ...over }) test('M9: im Abo-Modell mit abo_ende nennen News, Webshop und Buchungskalender den Löschtag (Frist der Funktion, Berliner Tag wie K39)', async () => { for (const [key, tage] of [['news', 30], ['shop', 90], ['unterkunft', 90]]) { assert.equal(loeschFristTage(key), tage, `Frist ${key}`) const v = await featureView(aus(key)) assert.equal(v.loeschungAm, tagNach(DISABLED_AT, tage), key) assert.deepEqual([v.disabledReason, v.disabledAt], ['abo_ende', DISABLED_AT]) } // ein fehlendes oder unlesbares disabledAt ergibt kein Datum assert.equal((await featureView(aus('shop', { disabledAt: '' }))).loeschungAm, null) assert.equal((await featureView(aus('news', { disabledAt: 'kaputt' }))).loeschungAm, null) }) test('M9: sonst bleibt es bei null (Team-Sperre, Bestand ohne Abo-Modell, ohne Sperre) und beim Terminplaner wie bisher', async () => { for (const key of ['news', 'shop', 'unterkunft']) { assert.equal((await featureView(aus(key, { disabledReason: 'team' }))).loeschungAm, null, `${key} Team`) assert.equal((await featureView(aus(key, { unlockedBy: 'kauf', einrichtungAbrechnung: undefined }))).loeschungAm, null, `${key} Bestand`) assert.equal((await featureView(aus(key, { state: 'active' }))).loeschungAm, null, `${key} aktiv`) } assert.equal((await featureView(aus('termine'))).loeschungAm, tagNach(DISABLED_AT, 30), 'Terminplaner wie bisher (30 Tage)') assert.equal((await featureView(aus('termine', { disabledReason: 'team', unlockedBy: 'kauf' }))).loeschungAm, tagNach(DISABLED_AT, 30), 'Terminplaner jeder Grund') })