mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 13:22:14 +00:00
test(01-10): add red assessment and records contracts
- pin honest assessment fallback, exhaustion, foreground, and state envelopes - require consistent save and empty-state add action grammar
This commit is contained in:
1 parent
d8e52b831d
commit
18d0facdfe
7 files changed
+362
-7
No files matched your search
@@ -80,6 +80,12 @@ beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
vi.mocked(prisma.appSettings.findUnique).mockResolvedValue(null as never);
|
||||
vi.mocked(requireModuleEnabled).mockResolvedValue({ enabled: true });
|
||||
vi.mocked(generateBiomarkerStatus).mockResolvedValue({
|
||||
hasProvider: true,
|
||||
text: "ok",
|
||||
cached: true,
|
||||
updatedAt: new Date().toISOString(),
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/insights/biomarker-assessment", () => {
|
||||
@@ -130,4 +136,68 @@ describe("GET /api/insights/biomarker-assessment", () => {
|
||||
const body = (await res.json()) as { meta?: { errorCode?: string } };
|
||||
expect(body.meta?.errorCode).toBe("assistant.disabled.insightStatus");
|
||||
});
|
||||
|
||||
it("preserves the safe terminal fallback produced when a causal claim is screened", async () => {
|
||||
vi.mocked(getSession).mockResolvedValue(SESSION_OK as never);
|
||||
vi.mocked(generateBiomarkerStatus).mockResolvedValueOnce({
|
||||
hasProvider: false,
|
||||
text: "The assessment could not be completed safely. Your recorded measurements remain available.",
|
||||
cached: true,
|
||||
updatedAt: null,
|
||||
});
|
||||
|
||||
const res = await callGet(makeReq("bm-screened"));
|
||||
const body = (await res.json()) as {
|
||||
data: {
|
||||
hasProvider: boolean;
|
||||
text: string | null;
|
||||
cached: boolean;
|
||||
updatedAt: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
expect(body.data).toEqual({
|
||||
hasProvider: false,
|
||||
text: "The assessment could not be completed safely. Your recorded measurements remain available.",
|
||||
cached: true,
|
||||
updatedAt: null,
|
||||
});
|
||||
expect(JSON.stringify(body)).not.toContain("medication caused");
|
||||
expect(JSON.stringify(body)).not.toContain("causal_claim");
|
||||
});
|
||||
|
||||
it("keeps a preparing cache miss distinct from a terminal negative cache", async () => {
|
||||
vi.mocked(getSession).mockResolvedValue(SESSION_OK as never);
|
||||
vi.mocked(generateBiomarkerStatus)
|
||||
.mockResolvedValueOnce({
|
||||
hasProvider: true,
|
||||
text: null,
|
||||
cached: false,
|
||||
updatedAt: null,
|
||||
preparing: true,
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
hasProvider: false,
|
||||
text: "Assessment temporarily unavailable. Your recorded measurements remain available.",
|
||||
cached: true,
|
||||
updatedAt: null,
|
||||
});
|
||||
|
||||
const preparing = await (await callGet(makeReq("bm-preparing"))).json();
|
||||
const negativeCache = await (await callGet(makeReq("bm-negative"))).json();
|
||||
|
||||
expect(preparing.data).toMatchObject({
|
||||
hasProvider: true,
|
||||
text: null,
|
||||
cached: false,
|
||||
preparing: true,
|
||||
});
|
||||
expect(negativeCache.data).toMatchObject({
|
||||
hasProvider: false,
|
||||
cached: true,
|
||||
text: expect.stringContaining("temporarily unavailable"),
|
||||
});
|
||||
expect(negativeCache.data).not.toHaveProperty("preparing", true);
|
||||
});
|
||||
});
|
||||
@@ -139,3 +139,52 @@ describe("metric subpages — retired range row + Letzte-Messung are gone", () =
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe("assessment presentation contract", () => {
|
||||
it("uses the shared readable foreground and compact rhythm for populated prose", () => {
|
||||
const cardSource = readFileSync(
|
||||
join(
|
||||
process.cwd(),
|
||||
"src",
|
||||
"components",
|
||||
"insights",
|
||||
"insight-status-card.tsx",
|
||||
),
|
||||
"utf8",
|
||||
);
|
||||
const moodSource = readFileSync(
|
||||
join(
|
||||
process.cwd(),
|
||||
"src",
|
||||
"components",
|
||||
"insights",
|
||||
"mood",
|
||||
"mood-insights-sections.tsx",
|
||||
),
|
||||
"utf8",
|
||||
);
|
||||
const moodBodySource = readFileSync(
|
||||
join(
|
||||
process.cwd(),
|
||||
"src",
|
||||
"components",
|
||||
"insights",
|
||||
"mood",
|
||||
"mood-better-days.tsx",
|
||||
),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
expect(cardSource).toContain(
|
||||
'className="animate-insight-in gap-2 py-3 md:py-4"',
|
||||
);
|
||||
expect(cardSource).toContain('className="text-foreground text-sm"');
|
||||
expect(moodSource).toContain(
|
||||
'className="animate-insight-in gap-2 py-3 md:py-4"',
|
||||
);
|
||||
expect(moodSource).toContain('data-slot="insight-assessment"');
|
||||
expect(moodBodySource).toContain(
|
||||
'className="text-foreground mb-2 text-sm"',
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user