import assert from "node:assert/strict"; import { existsSync, readFileSync } from "node:fs"; import { join } from "node:path"; import test from "node:test"; function source(path: string) { return readFileSync(join(process.cwd(), ...path.split("/")), "utf8"); } test("Rybbit tracking is mounted only in public audit presentation", () => { const publicAuditSource = source("components/public-audit/public-audit-page.tsx"); const dashboardLayoutSource = source("app/dashboard/layout.tsx"); const dashboardAnalyticsSource = source("app/dashboard/analytics/page.tsx"); assert.match(publicAuditSource, /RybbitTracking/); assert.match(publicAuditSource, /TrackedPublicAuditLink/); assert.doesNotMatch(dashboardLayoutSource, /RybbitTracking|rybbit/i); assert.doesNotMatch(dashboardAnalyticsSource, /next\/script|RybbitTracking/); }); test("internal Rybbit route fetches audit analytics on demand with graceful errors", () => { const routePath = "app/api/internal/rybbit/audit/route.ts"; assert.equal(existsSync(join(process.cwd(), ...routePath.split("/"))), true); const routeSource = source(routePath); assert.match(routeSource, /export async function GET/); assert.match(routeSource, /fetchRybbitAuditAnalytics/); assert.match(routeSource, /RYBBIT_API_KEY/); assert.match(routeSource, /return Response\.json\(\{ ok: false/); }); test("campaign metrics query exposes lightweight funnel and run metrics", () => { const metricsSource = source("convex/campaignMetrics.ts"); assert.match(metricsSource, /export const getDashboard = query/); for (const label of [ "foundLeads", "leadsWithContact", "missingContact", "auditsCreated", "approvalsOpen", "emailsSent", "followUpsPlanned", "followUpsSent", "responses", "conversations", "offers", "wins", "losses", "skippedDuplicates", "skippedBlacklisted", ]) { assert.match(metricsSource, new RegExp(label)); } }); test("analytics dashboard renders filters, Convex metrics, and Rybbit error states", () => { const pageSource = source("app/dashboard/analytics/page.tsx"); const componentSource = source("components/analytics/analytics-dashboard.tsx"); assert.doesNotMatch(pageSource, /DashboardPlaceholderPage/); assert.match(pageSource, /AnalyticsDashboard/); assert.match(componentSource, /api\.campaignMetrics\.getDashboard/); assert.match(componentSource, /\/api\/internal\/rybbit\/campaign/); assert.match(componentSource, /Kampagne/); assert.match(componentSource, /Nische/); assert.match(componentSource, /PLZ/); assert.match(componentSource, /Radius/); assert.match(componentSource, /Priorität/); assert.match(componentSource, /Status/); assert.match(componentSource, /Zeitraum/); assert.match(componentSource, /Rybbit-Daten konnten nicht geladen werden/); assert.match(componentSource, /Audit-Öffnungen/); assert.match(componentSource, /CTA-Klicks/); });