diff --git a/src/components/insights/__tests__/recommendations-grid-integration.test.tsx b/src/components/insights/__tests__/recommendations-grid-integration.test.tsx new file mode 100644 index 000000000..5a3806cdd --- /dev/null +++ b/src/components/insights/__tests__/recommendations-grid-integration.test.tsx @@ -0,0 +1,175 @@ +import { describe, it, expect, vi } from "vitest"; +import { renderToStaticMarkup } from "react-dom/server"; + +import { I18nProvider } from "@/lib/i18n/context"; +import { InsightAdvisorCard } from "../insight-advisor-card"; +import type { InsightResult, InsightRecommendation } from "@/lib/ai/types"; + +/** + * v1.4.16 phase B1b — full-flow integration: rationale (B5c) + + * confidence (B5d) + feedback (B5e) + grid wrapper (B1b) all paint + * together inside InsightAdvisorCard. + * + * The B5c report flagged that an e2e couldn't be added because + * `/insights` doesn't currently mount InsightAdvisorCard in the + * production tree. This integration test exercises the same surface + * via SSR and pins the cross-feature interaction so the rec card + * shell + per-card affordances all render in the right slots when + * the polished grid sits between InsightAdvisorCard and the + * RecommendationCard. + */ + +vi.mock("@/components/charts/health-chart", () => ({ + HealthChart: ({ + types, + mini, + windowOverride, + }: { + types: string[]; + mini?: boolean; + windowOverride?: string; + }) => ( +
+ ), +})); +vi.mock("@/components/charts/mood-chart", () => ({ + MoodChart: ({ mini }: { mini?: boolean }) => ( + + ), +})); +vi.mock("@tanstack/react-query", () => ({ + useQuery: () => ({ data: null, isLoading: false }), + useMutation: () => ({ + mutate: vi.fn(), + isPending: false, + isSuccess: false, + isError: false, + error: null, + }), + useQueryClient: () => ({ invalidateQueries: vi.fn() }), +})); +vi.mock("@/hooks/use-auth", () => ({ + useAuth: () => ({ + user: { id: "test-user", username: "tester", role: "USER" }, + isAuthenticated: true, + isLoading: false, + }), +})); + +function rec( + id: string, + severity: "info" | "suggestion" | "important" | "urgent", + text: string, + confidence: number, +): InsightRecommendation { + return { + id, + text, + severity, + confidence, + rationale: { + dataWindow: "last7days", + comparedTo: "your 90-day median", + deviation: "moderate deviation", + }, + metricSource: { + type: "weight", + timeRange: "last7days", + summary: "84.2 kg avg over 7 days", + }, + }; +} + +function buildInsight( + recommendations: InsightRecommendation[], +): InsightResult { + return { + insightType: "general", + summary: "Test summary", + classification: "gut", + classificationLabel: "Good", + findings: [], + correlations: [], + primaryRecommendation: "", + recommendations, + dataQuality: { coverage: "good", gaps: [], confidence: "hoch" }, + disclaimer: "Not medical advice.", + }; +} + +describe("InsightAdvisorCard + RecommendationsGrid full flow (B1b)", () => { + it("severity-orders the grid then paints confidence + feedback slots per card", () => { + const recs = [ + rec("a", "info", "info-text", 22), + rec("b", "urgent", "urgent-text", 88), + rec("c", "suggestion", "suggestion-text", 60), + ]; + const html = renderToStaticMarkup( +