Files

198 lines
7.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// testApp.js zuerst: es prueft beim Laden, dass useTestEnv() vor config.js gelaufen ist
import { sessionCookie } from './testApp.js'
import { config } from '../../server/config.js'
/**
* Feste Testdaten für die Routen-Tests (Aufgaben 7–13): Kunden c1–c4, Abo-Dokumente, Zustimmung,
* Session-Cookies. seedFixtures(aw) legt Kunden und Abos in den Appwrite-Nachbau; c3 hat kein Abo
* (Neuabschluss-Tests), c4 ist ein Testkonto (ABO_TEST_EMAILS=test@example.invalid im Test setzen).
* Erst nach useTestEnv() dynamisch importieren (siehe testApp.js).
*/
const DAY_MS = 86400000
// Sekundengenau wie Stripe (unix-Zeitstempel): der Spiegel schreibt toIso(unix) und trifft so die
// Fixture-Werte wortgleich (z. B. storagePaidPeriodEnd = currentPeriodEnd nach einem Speicher-Plus)
const daysFromNow = (days) => new Date(Math.floor((Date.now() + days * DAY_MS) / 1000) * 1000).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 },
c4: { $id: 'c4', appwriteUserId: 'u4', email: 'test@example.invalid', name: 'Testkonto', status: 'active', portalAccessEnabled: true },
}
/** Abo-Dokument mit id als Dokument-ID und Stripe-Abo-ID (in Produktion immer gleich). */
export const subscriptionDoc = (id, overrides = {}) => ({ ...overrides, $id: id, stripeSubscriptionId: id })
// 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 = subscriptionDoc('sub_h', {
customerId: 'c1',
email: 'k@example.invalid',
stripeCustomerId: 'cus_c1',
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 per subscriptionDoc('sub_h', { ...wartungDoc }) eingespielt). */
export const wartungDoc = subscriptionDoc('sub_w', {
...hostingDoc,
productKey: 'wartung',
planKey: config.products.wartung.lookupKey,
priceAmount: config.products.wartung.amountCents,
})
/** Zweites Hosting-Abo sub_h2 von c2. */
export const hosting2Doc = subscriptionDoc('sub_h2', {
...hostingDoc,
customerId: 'c2',
email: 'k2@example.invalid',
stripeCustomerId: 'cus_c2',
})
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}`,
name: customers[customerId]?.name || '', // wie beim echten Login (auth.js)
email: customers[customerId]?.email || '',
})
/** Alte Mitarbeiter-Sitzung im Portal (Login bis Etappe 4): /api/auth/me beendet sie, Kunden-Routen 401. */
export const adminCookie = () =>
sessionCookie({ role: 'admin', appwriteUserId: 'u_admin', name: 'Kenso', email: 'kenso@webklar.com' })
/** Alte Ansicht "Als Kunde ansehen" aus dem frueheren Admin-Panel (ohne viewId): gilt als beendet (401 view_expired). */
export const viewAsCookie = (customerId = 'c1') =>
sessionCookie({
role: 'admin',
viewAs: true,
isAdmin: true,
appwriteUserId: 'u_admin',
adminName: 'Kenso',
adminEmail: 'kenso@webklar.com',
customerId,
name: customers[customerId]?.name || '',
email: customers[customerId]?.email || '',
})
/** Kundenansicht aus dem Ticketsystem (Einmal-Link, 2 h, Kennung viewId): Mitarbeiter Andrej ohne Admin-Label. */
export const kundenansichtCookie = ({ customerId = 'c1', viewId = 'a'.repeat(32), viewExpiresAt = Date.now() + 3600000 } = {}) =>
sessionCookie({
role: 'admin',
viewAs: true,
viewId,
viewExpiresAt,
isAdmin: false,
appwriteUserId: 'u_staff2',
adminName: 'Andrej',
adminEmail: 'andrej@webklar.com',
customerId,
name: customers[customerId]?.name || '',
email: customers[customerId]?.email || '',
})
/** Kunden c1–c4 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. Die Standard-ID ist 28 Zeichen lang wie
* bei Stripe (sub_ + 24); fuer den Spiegel von sub_h explizit id: 'sub_h' uebergeben. metadata
* ergaenzt/ueberschreibt die Zustimmungsdaten, rest alles Weitere (status, cancel_at, ...).
*/
export function stripeSubscription({
id = 'sub_1SD6vPRxAbCdEfGhIjKlMnOp',
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,
}
}