Schema: - 8 neue Profile-Felder fuer DiGA-Demographics (birthYear/gender/maritalStatus/ profession/bundesland/city + 2 consent-stamps demographicsConsentAt/ demographicsWithdrawnAt) - 4 Pro-Trial-Felder (proTrialStartedAt/ExpiresAt/Source/UsedAt) — Free-User bekommen 1 Woche Pro als Reward fuer DiGA-Daten-Pflege (siehe project_demographic_pro_trial_reward.md) - lyra_voice_id (Legend-only Voice-Picker) - diga_banner_dismissed_at (server-side persistence ueber Re-Install) - last_install_at (Streak-Logic survives Re-Install) - Migration 20260507_profile_demographics_and_trial: alle Felder optional, keine Backfill-Logik notwendig Endpoints (alle auth-protected, scope=me): - GET /api/profile/me/sos-insights - GET /api/profile/me/cooldown-history - GET /api/profile/me/approved-domains - POST /api/profile/me/install-event (track app re-installs) - POST /api/profile/me/diga-banner-dismiss - PATCH /api/profile/me/demographics (consent-stamp + re-grant-after-withdrawal in tx) - DELETE /api/profile/me/demographics (DSGVO right-to-be-forgotten) Plugin: - pro-trial-expiry-cron: 6h-Interval, conservative-fallback (revoke nur wenn kein stripeSubId), 60s initial-delay damit Server-boot nicht blockiert wird Tests: - vitest config + erste Test-Files (test-infrastructure setup) Memory: - feedback_demographics_user_initiated.md (Lyra darf NIE extrahieren) - project_demographic_pro_trial_reward.md (Pro-Trial-Reward-Mechanik) - project_profile_page_design.md (UI-Showpiece, eigene/fremde-Ansicht streng getrennt) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
/**
|
|
* Vitest test setup.
|
|
*
|
|
* Backend uses Nitro auto-imports (defineEventHandler, requireUser, etc.) which
|
|
* are injected at build time via unimport. In unit tests we don't actually
|
|
* boot Nitro; we test pure logic + DB-layer functions in isolation.
|
|
*
|
|
* For endpoint-handler tests we either:
|
|
* 1. Test the underlying db/* function directly (preferred — easy to mock)
|
|
* 2. Stub Nitro globals (defineEventHandler etc.) — see below
|
|
*
|
|
* Stubs intentionally minimal — when we need full request-cycle tests we'll
|
|
* add supertest + nitro `.output/server` boot (see ops/TESTING_STATE.md §4).
|
|
*/
|
|
import { vi } from "vitest";
|
|
|
|
// ─── Nitro / h3 globals ─────────────────────────────────────────────────────
|
|
// These are injected at build time via Nitro's unimport. In tests we stub
|
|
// the most-used ones so endpoint files can be imported (or referenced) without
|
|
// crashing. Add more as test surface grows.
|
|
const g = globalThis as Record<string, unknown>;
|
|
|
|
if (typeof g.defineEventHandler === "undefined") {
|
|
g.defineEventHandler = (handler: unknown) => handler;
|
|
}
|
|
if (typeof g.defineNitroPlugin === "undefined") {
|
|
g.defineNitroPlugin = (handler: unknown) => handler;
|
|
}
|
|
if (typeof g.createError === "undefined") {
|
|
g.createError = ({
|
|
statusCode,
|
|
message,
|
|
data,
|
|
}: {
|
|
statusCode?: number;
|
|
message?: string;
|
|
data?: unknown;
|
|
}) => {
|
|
const err = new Error(message ?? "error") as Error & {
|
|
statusCode?: number;
|
|
data?: unknown;
|
|
};
|
|
err.statusCode = statusCode;
|
|
err.data = data;
|
|
return err;
|
|
};
|
|
}
|
|
if (typeof g.readBody === "undefined") {
|
|
g.readBody = vi.fn(async (event: { body?: unknown }) => event.body);
|
|
}
|
|
if (typeof g.getQuery === "undefined") {
|
|
g.getQuery = vi.fn((event: { query?: unknown }) => event.query ?? {});
|
|
}
|
|
if (typeof g.getHeader === "undefined") {
|
|
g.getHeader = vi.fn(() => undefined);
|
|
}
|
|
if (typeof g.setResponseStatus === "undefined") {
|
|
g.setResponseStatus = vi.fn();
|
|
}
|
|
if (typeof g.setHeader === "undefined") {
|
|
g.setHeader = vi.fn();
|
|
}
|
|
if (typeof g.useRuntimeConfig === "undefined") {
|
|
g.useRuntimeConfig = vi.fn(() => ({
|
|
public: { supabase: { url: "", key: "" } },
|
|
supabase: { url: "", key: "" },
|
|
}));
|
|
}
|
|
if (typeof g.usePrisma === "undefined") {
|
|
// Tests should override per-test via vi.mock("../../server/utils/prisma")
|
|
g.usePrisma = vi.fn(() => {
|
|
throw new Error("usePrisma not mocked in this test");
|
|
});
|
|
}
|