// testApp.js zuerst: es prueft beim Laden, dass useTestEnv() gelaufen ist, bevor config.js die Umgebung liest import { sessionCookie } from './testApp.js' import { config } from '../../server/config.js' /** * Feste Testdaten für die Routen-Tests (Aufgaben 7–13): Kunden c1–c3, Abo-Dokumente, Zustimmung, * Session-Cookies. seedFixtures(aw) legt Kunden und Abos in den Appwrite-Nachbau; c3 hat kein Abo * (Neuabschluss-Tests). Erst nach useTestEnv() dynamisch importieren (siehe testApp.js). */ const DAY_MS = 86400000 const daysFromNow = (days) => new Date(Date.now() + days * DAY_MS).toISOString() export const customers = { c1: { $id: 'c1', appwriteUserId: 'u1', email: 'k@example.invalid', name: 'Kunde Eins', status: 'active', portalAccessEnabled: true }, c2: { $id: 'c2', appwriteUserId: 'u2', email: 'k2@example.invalid', name: 'Kunde Zwei', status: 'active', portalAccessEnabled: true }, c3: { $id: 'c3', appwriteUserId: 'u3', email: 'k3@example.invalid', name: 'Kunde Drei', status: 'active', portalAccessEnabled: true }, } // Abo seit 40 Tagen (Widerrufsfrist des Abschlusses vorbei), naechste Abbuchung in 20 Tagen const startedAt = daysFromNow(-40) /** Hosting-Abo sub_h von c1: aktiv, Fassung 4, ohne Zusatzspeicher. */ export const hostingDoc = { $id: 'sub_h', customerId: 'c1', email: 'k@example.invalid', stripeCustomerId: 'cus_c1', stripeSubscriptionId: 'sub_h', status: 'active', productKey: 'hosting', planKey: config.products.hosting.lookupKey, priceAmount: config.products.hosting.amountCents, startedAt, termStartAt: startedAt, currentPeriodEnd: daysFromNow(20), trialEnd: null, cancelAtPeriodEnd: false, cancelAt: null, canceledAt: null, endedAt: null, termsVersion: config.abo.termsVersion, termsAcceptedAt: startedAt, earlyStartConsentAt: startedAt, startChoice: 'sofort', consentIp: '127.0.0.1', consentUserAgent: 'test', consentTextVersion: config.abo.termsVersion, storageUnits: 0, storagePaidUnits: 0, storagePaidPeriodEnd: null, } /** Wartungs-Abo sub_w von c1 (im Test meist als sub_h eingespielt, damit c1 nur ein Abo hat). */ export const wartungDoc = { ...hostingDoc, $id: 'sub_w', stripeSubscriptionId: 'sub_w', productKey: 'wartung', planKey: config.products.wartung.lookupKey, priceAmount: config.products.wartung.amountCents, } /** Zweites Hosting-Abo sub_h2 von c2. */ export const hosting2Doc = { ...hostingDoc, $id: 'sub_h2', customerId: 'c2', email: 'k2@example.invalid', stripeCustomerId: 'cus_c2', stripeSubscriptionId: 'sub_h2', } const consentAt = new Date().toISOString() /** Zustimmung im Portal (Bestellung, Wechsel, Speicher-Plus); earlyStartConsentAt fuer den Wechsel (F16). */ export const consent = { termsVersion: config.abo.termsVersion, consentAt, consentIp: '127.0.0.1', consentUserAgent: 'test', earlyStartConsentAt: consentAt, } /** Kunden-Session; Standard c1. */ export const customerCookie = (customerId = 'c1') => sessionCookie({ customerId, appwriteUserId: customers[customerId]?.appwriteUserId || `u_${customerId}` }) /** Admin-Session (Ticketsystem-Mitarbeiter im Portal), F11. */ export const adminCookie = () => sessionCookie({ role: 'admin', appwriteUserId: 'u_admin', name: 'Kenso', email: 'kenso@webklar.com' }) /** Kunden c1–c3 und die Abos sub_h (c1) und sub_h2 (c2) in den Appwrite-Nachbau legen. */ export function seedFixtures(aw) { for (const customer of Object.values(customers)) aw.seed('customers', customer) aw.seed('subscriptions', hostingDoc) aw.seed('subscriptions', hosting2Doc) } const unix = (iso) => Math.floor(new Date(iso).getTime() / 1000) /** * Stripe-Abo in der Form der SDK-API-Version für den Stripe-Nachbau: Abo-Posten je Produkt, * dazu ein Zusatzspeicher-Posten, wenn storageUnits > 0. metadata ergaenzt/ueberschreibt die * Zustimmungsdaten, rest alles Weitere (status, cancel_at, ...). */ export function stripeSubscription({ id = 'sub_h', customerId = 'c1', productKey = 'hosting', storageUnits = 0, metadata = {}, ...rest } = {}) { const product = config.products[productKey] const items = [ { id: `si_${id}_abo`, object: 'subscription_item', quantity: 1, price: { id: `price_${productKey}`, object: 'price', lookup_key: product.lookupKey, unit_amount: product.amountCents }, }, ] if (storageUnits > 0) { items.push({ id: `si_${id}_speicher`, object: 'subscription_item', quantity: storageUnits, price: { id: 'price_mailStorage', object: 'price', lookup_key: config.mailStorage.lookupKey, unit_amount: config.mailStorage.amountCents }, }) } return { id, object: 'subscription', status: 'active', customer: `cus_${customerId}`, start_date: unix(hostingDoc.startedAt), current_period_end: unix(hostingDoc.currentPeriodEnd), trial_end: null, cancel_at_period_end: false, cancel_at: null, canceled_at: null, ended_at: null, metadata: { webklarCustomerId: customerId, email: customers[customerId]?.email || '', productKey, termsVersion: config.abo.termsVersion, consentTextVersion: config.abo.termsVersion, termsAcceptedAt: consentAt, startChoice: 'sofort', earlyStartConsentAt: consentAt, consentIp: '127.0.0.1', consentUserAgent: 'test', ...metadata, }, items: { object: 'list', data: items }, ...rest, } }