import { test, beforeEach, afterEach } from 'node:test' import assert from 'node:assert/strict' import { config } from '../server/config.js' import { zeitenAus, zeitenFuerKunde, zeitenModus } from '../server/services/zeiten/schalter.js' const ZEITEN_ENV = [ 'ZEITEN_ENABLED', 'ZEITEN_PILOT_EMAILS', 'ZEITEN_KEIN_NEUBAU', 'APPWRITE_COLLECTION_OEFFNUNGSZEITEN', 'APPWRITE_COLLECTION_ZEITEN_ERINNERUNGEN', ] let original beforeEach(() => { original = { ...config.zeiten } }) afterEach(() => { Object.assign(config.zeiten, original) }) /** Frische config.js-Instanz mit genau diesen Zeiten-Umgebungsvariablen (alle anderen entfernt). */ let freshCounter = 0 async function freshConfig(env = {}) { const saved = Object.fromEntries(ZEITEN_ENV.map((key) => [key, process.env[key]])) for (const key of ZEITEN_ENV) delete process.env[key] Object.assign(process.env, env) try { freshCounter += 1 return (await import(`../server/config.js?zeiten-test=${freshCounter}`)).config } finally { for (const key of ZEITEN_ENV) { if (saved[key] === undefined) delete process.env[key] else process.env[key] = saved[key] } } } test('Vorgabe ist aus', async () => { const fresh = await freshConfig() assert.deepEqual(fresh.zeiten, { mode: 'off', pilotEmails: [], keinNeubau: ['emmas-schatzkiste'] }) // ZEITEN_ENABLED leer ⇒ aus; der Schalter liest config.zeiten bei jedem Aufruf config.zeiten.mode = fresh.zeiten.mode assert.equal(zeitenModus(), 'off') assert.equal(zeitenAus(), true) assert.equal(zeitenFuerKunde('kenso.gri@gmail.com'), false) }) test('Konfiguration: leerer oder unbekannter Schalter ist off, Umgebungsvariablen werden bereinigt', async () => { for (const value of ['', ' ', 'banane', 'true', '1']) { assert.equal((await freshConfig({ ZEITEN_ENABLED: value })).zeiten.mode, 'off', `ZEITEN_ENABLED=${JSON.stringify(value)}`) } assert.equal((await freshConfig({ ZEITEN_ENABLED: ' ON ' })).zeiten.mode, 'on') const fresh = await freshConfig({ ZEITEN_ENABLED: ' Pilot ', ZEITEN_PILOT_EMAILS: ' Kenso.Gri@Gmail.com, ,justin@webklar.com ', }) assert.equal(fresh.zeiten.mode, 'pilot') assert.deepEqual(fresh.zeiten.pilotEmails, ['kenso.gri@gmail.com', 'justin@webklar.com']) }) test('zeitenModus: leer und unbekannt sind off, pilot und on bleiben', () => { for (const value of [undefined, null, '', 'banane', 'PILOT', 'true']) { config.zeiten.mode = value assert.equal(zeitenModus(), 'off', `mode=${JSON.stringify(value)}`) assert.equal(zeitenAus(), true) } config.zeiten.mode = 'pilot' assert.equal(zeitenModus(), 'pilot') assert.equal(zeitenAus(), false) config.zeiten.mode = 'on' assert.equal(zeitenModus(), 'on') assert.equal(zeitenAus(), false) }) test('off sperrt alle, auch mit Stern in der Liste', () => { config.zeiten.mode = 'off' config.zeiten.pilotEmails = ['*', 'kenso.gri@gmail.com'] assert.equal(zeitenFuerKunde('kenso.gri@gmail.com'), false) assert.equal(zeitenFuerKunde('jemand@example.com'), false) }) test('pilot gilt nur für die Pilotliste', () => { config.zeiten.mode = 'pilot' config.zeiten.pilotEmails = ['a@b.de'] assert.equal(zeitenFuerKunde('A@b.de'), true) assert.equal(zeitenFuerKunde(' a@b.de '), true) assert.equal(zeitenFuerKunde('x@y.de'), false) assert.equal(zeitenFuerKunde('a@b.de.evil.de'), false) // Stern = alle, leere Liste = niemand, ohne Adresse = niemand config.zeiten.pilotEmails = ['*'] assert.equal(zeitenFuerKunde('x@y.de'), true) config.zeiten.pilotEmails = [] assert.equal(zeitenFuerKunde('a@b.de'), false) config.zeiten.pilotEmails = ['a@b.de'] for (const email of [undefined, null, '', ' ']) assert.equal(zeitenFuerKunde(email), false) }) test('on gilt für alle', () => { config.zeiten.mode = 'on' config.zeiten.pilotEmails = ['a@b.de'] assert.equal(zeitenFuerKunde('x@y.de'), true) assert.equal(zeitenFuerKunde(undefined), true) }) test('keinNeubau kommt aus ZEITEN_KEIN_NEUBAU, Vorgabe emmas-schatzkiste', async () => { assert.deepEqual((await freshConfig()).zeiten.keinNeubau, ['emmas-schatzkiste']) assert.deepEqual((await freshConfig({ ZEITEN_KEIN_NEUBAU: '' })).zeiten.keinNeubau, ['emmas-schatzkiste']) assert.deepEqual( (await freshConfig({ ZEITEN_KEIN_NEUBAU: ' Emmas-Schatzkiste, , Andere-Site ' })).zeiten.keinNeubau, ['emmas-schatzkiste', 'andere-site'], ) }) test('zeiten steht neben config.termine, nicht darin', async () => { const fresh = await freshConfig() assert.equal('keinNeubau' in fresh.termine, false) assert.equal('zeiten' in fresh.termine, false) assert.notEqual(fresh.zeiten, fresh.termine) }) test('zeitenSetup: 3000 Cent einmalig', async () => { const fresh = await freshConfig() assert.deepEqual(fresh.zeitenSetup, { key: 'zeitenSetup', name: 'Öffnungszeiten live – Einrichtung', amountCents: 3000, lookupKey: 'webklar_zeiten_einrichtung_3000', oneTime: true, priceNickname: 'Öffnungszeiten-Einrichtung 30 €', }) assert.equal(config.zeitenSetup.amountCents, 3000) assert.equal(config.zeitenSetup.oneTime, true) assert.equal(config.zeitenSetup.lookupKey, 'webklar_zeiten_einrichtung_3000') }) test('Konfiguration: Collection-IDs der Zeiten-Collections', async () => { const fresh = await freshConfig() assert.equal(fresh.collections.oeffnungszeiten, 'oeffnungszeiten') assert.equal(fresh.collections.zeitenErinnerungen, 'zeitenErinnerungen') const anders = await freshConfig({ APPWRITE_COLLECTION_OEFFNUNGSZEITEN: 'zDaten', APPWRITE_COLLECTION_ZEITEN_ERINNERUNGEN: 'zMerker', }) assert.deepEqual([anders.collections.oeffnungszeiten, anders.collections.zeitenErinnerungen], ['zDaten', 'zMerker']) })