import { test, beforeEach, afterEach } from 'node:test' import assert from 'node:assert/strict' import path from 'node:path' import { config } from '../server/config.js' import { shopFuerKunde, shopModus } from '../server/services/shop/schalter.js' const SHOP_ENV = [ 'SHOP_ENABLED', 'SHOP_PILOT_EMAILS', 'SHOP_UPLOAD_DIR', 'STRIPE_CONNECT_WEBHOOK_SECRET', 'APPWRITE_COLLECTION_SHOP_CONFIG', 'APPWRITE_COLLECTION_SHOP_PRODUCTS', 'APPWRITE_COLLECTION_SHOP_ORDERS', 'APPWRITE_COLLECTION_SHOP_WIDERRUFE', ] let original beforeEach(() => { original = { ...config.shop } }) afterEach(() => { Object.assign(config.shop, original) }) /** Frische config.js-Instanz mit genau diesen Shop-Umgebungsvariablen (alle anderen entfernt). */ let freshCounter = 0 async function freshConfig(env = {}) { const saved = Object.fromEntries(SHOP_ENV.map((key) => [key, process.env[key]])) for (const key of SHOP_ENV) delete process.env[key] Object.assign(process.env, env) try { freshCounter += 1 return (await import(`../server/config.js?shop-test=${freshCounter}`)).config } finally { for (const key of SHOP_ENV) { if (saved[key] === undefined) delete process.env[key] else process.env[key] = saved[key] } } } test('Konfiguration: Vorgaben ohne Umgebungsvariablen', async () => { const fresh = await freshConfig() assert.deepEqual(fresh.shop, { mode: 'off', pilotEmails: [], fassung: '2026-10-05', uploadDir: path.join(process.cwd(), 'upload-data', 'shop'), connectWebhookSecret: '', bestellAblaufMinuten: 30, maxArtikel: 500, maxBilder: 4, maxVarianten: 30, anonymisierenJahre: 3, loeschTageNachAbschalten: 90, unbezahltLoeschTage: 30, formMinSekunden: 3, minAntwortMs: 300, }) assert.equal(fresh.collections.shopConfig, 'shopConfig') assert.equal(fresh.collections.shopProducts, 'shopProducts') assert.equal(fresh.collections.shopOrders, 'shopOrders') assert.equal(fresh.collections.shopWiderrufe, 'shopWiderrufe') }) test('Konfiguration: Umgebungsvariablen werden gelesen und bereinigt', async () => { const fresh = await freshConfig({ SHOP_ENABLED: ' Pilot ', SHOP_PILOT_EMAILS: ' Kenso.Gri@Gmail.com, ,justin@webklar.com ', SHOP_UPLOAD_DIR: '/tmp/shop-bilder', STRIPE_CONNECT_WEBHOOK_SECRET: 'whsec_connect', APPWRITE_COLLECTION_SHOP_CONFIG: 'sConfig', APPWRITE_COLLECTION_SHOP_PRODUCTS: 'sProducts', APPWRITE_COLLECTION_SHOP_ORDERS: 'sOrders', APPWRITE_COLLECTION_SHOP_WIDERRUFE: 'sWiderrufe', }) assert.equal(fresh.shop.mode, 'pilot') assert.deepEqual(fresh.shop.pilotEmails, ['kenso.gri@gmail.com', 'justin@webklar.com']) assert.equal(fresh.shop.uploadDir, '/tmp/shop-bilder') assert.equal(fresh.shop.connectWebhookSecret, 'whsec_connect') assert.deepEqual( [fresh.collections.shopConfig, fresh.collections.shopProducts, fresh.collections.shopOrders, fresh.collections.shopWiderrufe], ['sConfig', 'sProducts', 'sOrders', 'sWiderrufe'], ) }) test('Konfiguration: leerer oder unbekannter Schalter ist off', async () => { for (const value of ['', ' ', 'banane', 'true', '1', 'ON ']) { const fresh = await freshConfig({ SHOP_ENABLED: value }) assert.equal(fresh.shop.mode, value.trim().toLowerCase() === 'on' ? 'on' : 'off', `SHOP_ENABLED=${JSON.stringify(value)}`) } }) test('Konfiguration: Katalogeintrag shopSetup', () => { assert.deepEqual(config.shopSetup, { key: 'shopSetup', name: 'Webshop – Einrichtung', amountCents: 29900, lookupKey: 'webklar_shop_einrichtung_29900', oneTime: true, priceNickname: 'Webshop-Einrichtung 299 €', }) }) test('shopModus: leer und unbekannt sind off, pilot und on bleiben', () => { for (const value of [undefined, null, '', 'banane', 'PILOT', 'true']) { config.shop.mode = value assert.equal(shopModus(), 'off', `mode=${JSON.stringify(value)}`) } config.shop.mode = 'pilot' assert.equal(shopModus(), 'pilot') config.shop.mode = 'on' assert.equal(shopModus(), 'on') }) test('shopModus: Aenderung von config.shop.mode wirkt sofort', () => { config.shop.mode = 'off' assert.equal(shopModus(), 'off') config.shop.mode = 'on' assert.equal(shopModus(), 'on') config.shop.mode = 'off' assert.equal(shopModus(), 'off') }) test('shopFuerKunde: off sperrt alle, auch mit Stern in der Liste', () => { config.shop.mode = 'off' config.shop.pilotEmails = ['*', 'kenso.gri@gmail.com'] assert.equal(shopFuerKunde('kenso.gri@gmail.com'), false) assert.equal(shopFuerKunde('jemand@example.com'), false) }) test('shopFuerKunde: pilot erlaubt nur Adressen der Liste, Schreibweise egal', () => { config.shop.mode = 'pilot' config.shop.pilotEmails = ['kenso.gri@gmail.com'] assert.equal(shopFuerKunde('kenso.gri@gmail.com'), true) assert.equal(shopFuerKunde(' Kenso.Gri@Gmail.com '), true) assert.equal(shopFuerKunde('jemand@example.com'), false) assert.equal(shopFuerKunde(''), false) assert.equal(shopFuerKunde(undefined), false) assert.equal(shopFuerKunde(null), false) }) test('shopFuerKunde: pilot mit leerer Liste laesst niemanden durch, Stern alle (auch ohne Adresse)', () => { config.shop.mode = 'pilot' config.shop.pilotEmails = [] assert.equal(shopFuerKunde('kenso.gri@gmail.com'), false) assert.equal(shopFuerKunde(''), false) config.shop.pilotEmails = ['*'] assert.equal(shopFuerKunde('jemand@example.com'), true) assert.equal(shopFuerKunde(''), true) }) test('shopFuerKunde: on erlaubt alle Kunden, die Liste spielt keine Rolle', () => { config.shop.mode = 'on' config.shop.pilotEmails = [] assert.equal(shopFuerKunde('jemand@example.com'), true) assert.equal(shopFuerKunde(''), true) }) test('shopFuerKunde: Unbekannter Modus gilt als off', () => { config.shop.mode = 'banane' config.shop.pilotEmails = ['*'] assert.equal(shopFuerKunde('kenso.gri@gmail.com'), false) })