mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 12:22:03 +00:00
style: prettier on W5 reconcile touchpoints
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b094eaa2ae
commit
bbdc3fbd00
9 files changed
+32
-39
No files matched your search
@@ -70,9 +70,7 @@ describe("proxy.ts onboarding redirect (v1.4.22 C4)", () => {
|
||||
});
|
||||
|
||||
it("does NOT redirect from /auth/login", () => {
|
||||
const res = proxy(
|
||||
makeRequest("/auth/login", { hl_onboarding: "pending" }),
|
||||
);
|
||||
const res = proxy(makeRequest("/auth/login", { hl_onboarding: "pending" }));
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.headers.get("location")).toBeNull();
|
||||
});
|
||||
|
||||
@@ -408,9 +408,7 @@ async function streamRefusal(args: {
|
||||
});
|
||||
|
||||
const stream = createSseStream((controller) => {
|
||||
controller.enqueue(
|
||||
encodeFrame({ type: "token", token: args.refusalText }),
|
||||
);
|
||||
controller.enqueue(encodeFrame({ type: "token", token: args.refusalText }));
|
||||
controller.enqueue(
|
||||
encodeFrame({
|
||||
type: "done",
|
||||
|
||||
@@ -141,9 +141,7 @@ describe("ApiTokenOverviewSection — responsive", () => {
|
||||
// two date columns (text-right + text-xs is unique to those cells)
|
||||
// and assert none carries whitespace-nowrap.
|
||||
const dateCellMatches =
|
||||
tableMarkup.match(
|
||||
/<td[^>]*\btext-right\b[^>]*\btext-xs\b[^>]*>/g,
|
||||
) ?? [];
|
||||
tableMarkup.match(/<td[^>]*\btext-right\b[^>]*\btext-xs\b[^>]*>/g) ?? [];
|
||||
expect(dateCellMatches.length).toBeGreaterThanOrEqual(2);
|
||||
for (const cell of dateCellMatches) {
|
||||
expect(cell).not.toContain("whitespace-nowrap");
|
||||
|
||||
@@ -242,10 +242,7 @@ export function TrendCard({
|
||||
full layout returns at `>=sm`. */}
|
||||
{compareBaseline !== "none" && compareDelta != null && (
|
||||
<div
|
||||
className={cn(
|
||||
"mt-1",
|
||||
avgAllTime !== undefined && "hidden sm:block",
|
||||
)}
|
||||
className={cn("mt-1", avgAllTime !== undefined && "hidden sm:block")}
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
@@ -331,16 +328,10 @@ export function TrendCard({
|
||||
combined secondary row below so the tile keeps the same
|
||||
vertical density as every other trend card. */}
|
||||
{avgAllTime !== undefined && (
|
||||
<span
|
||||
data-slot="trend-card-all-time"
|
||||
className="hidden sm:inline"
|
||||
>
|
||||
<span data-slot="trend-card-all-time" className="hidden sm:inline">
|
||||
{t(avgAllTimeLabelKey)}:{" "}
|
||||
<span
|
||||
className={cn(
|
||||
"font-medium tabular-nums",
|
||||
avgAllTimeColorClass,
|
||||
)}
|
||||
className={cn("font-medium tabular-nums", avgAllTimeColorClass)}
|
||||
>
|
||||
{avgAllTime !== null ? formatValue(avgAllTime) : "—"}
|
||||
</span>
|
||||
@@ -360,10 +351,7 @@ export function TrendCard({
|
||||
<span>
|
||||
{t(avgAllTimeLabelKey)}:{" "}
|
||||
<span
|
||||
className={cn(
|
||||
"font-medium tabular-nums",
|
||||
avgAllTimeColorClass,
|
||||
)}
|
||||
className={cn("font-medium tabular-nums", avgAllTimeColorClass)}
|
||||
>
|
||||
{avgAllTime !== null ? formatValue(avgAllTime) : "—"}
|
||||
</span>
|
||||
|
||||
@@ -21,7 +21,12 @@ const useAuthMock = vi.fn<
|
||||
isLoading: boolean;
|
||||
}
|
||||
>(() => ({
|
||||
user: { id: "test-user", username: "tester", role: "USER", gravatarUrl: null },
|
||||
user: {
|
||||
id: "test-user",
|
||||
username: "tester",
|
||||
role: "USER",
|
||||
gravatarUrl: null,
|
||||
},
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
}));
|
||||
@@ -335,7 +340,9 @@ describe("<MessageThread>", () => {
|
||||
const html = render(<MessageThread conversation={withKeyValues} />);
|
||||
expect(html).toContain("30-day adherence");
|
||||
// No stray empty unit/window markup.
|
||||
expect(html).not.toMatch(/30-day adherence:\s*<\/span>\s*<strong[^>]*>\s*</);
|
||||
expect(html).not.toMatch(
|
||||
/30-day adherence:\s*<\/span>\s*<strong[^>]*>\s*</,
|
||||
);
|
||||
});
|
||||
|
||||
it("hides the disclosure entirely when keyValues is empty or absent", () => {
|
||||
@@ -365,7 +372,9 @@ describe("<MessageThread>", () => {
|
||||
expect(html).toMatch(
|
||||
/<img[^>]+src="https:\/\/www\.gravatar\.com\/avatar\/abc123/,
|
||||
);
|
||||
expect(html).toMatch(/data-slot="coach-bubble-user-avatar"[^>]*class="[^"]*size-8/);
|
||||
expect(html).toMatch(
|
||||
/data-slot="coach-bubble-user-avatar"[^>]*class="[^"]*size-8/,
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back to initials when no Gravatar URL is present", () => {
|
||||
|
||||
@@ -316,7 +316,7 @@ function ChatBubble({
|
||||
className={cn(
|
||||
"text-muted-foreground hover:text-foreground flex cursor-pointer",
|
||||
"items-center gap-1.5 leading-relaxed",
|
||||
"[&::-webkit-details-marker]:hidden marker:hidden",
|
||||
"marker:hidden [&::-webkit-details-marker]:hidden",
|
||||
"focus-visible:ring-ring/50 rounded outline-none focus-visible:ring-2",
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
parseKeyValueLine,
|
||||
parseKeyValuesSentinel,
|
||||
} from "../keyvalues";
|
||||
import { parseKeyValueLine, parseKeyValuesSentinel } from "../keyvalues";
|
||||
|
||||
/**
|
||||
* v1.4.22 Wave 3 B1+B2 — Coach evidence-block sentinel parser.
|
||||
*/
|
||||
describe("parseKeyValueLine", () => {
|
||||
it("parses a full line with unit + window", () => {
|
||||
expect(parseKeyValueLine("avg30 systolic: 138 [mmHg] (last30days)")).toEqual({
|
||||
expect(
|
||||
parseKeyValueLine("avg30 systolic: 138 [mmHg] (last30days)"),
|
||||
).toEqual({
|
||||
label: "avg30 systolic",
|
||||
value: "138",
|
||||
unit: "mmHg",
|
||||
|
||||
@@ -39,7 +39,9 @@ describe("getCoachSystemPrompt — EN", () => {
|
||||
expect(prompt).toMatch(/GROUND RULES/);
|
||||
expect(prompt).toMatch(/1\. Prose-first\./);
|
||||
expect(prompt).toMatch(/2\. Values belong in the evidence block\./);
|
||||
expect(prompt).toMatch(/3\. Missing data is an invitation, not a refusal\./);
|
||||
expect(prompt).toMatch(
|
||||
/3\. Missing data is an invitation, not a refusal\./,
|
||||
);
|
||||
expect(prompt).toMatch(/4\. Conservative phrasing\./);
|
||||
expect(prompt).toMatch(/5\. Motivational-interviewing micro-moves\./);
|
||||
expect(prompt).toMatch(/6\. Redirect off-topic input gracefully\./);
|
||||
@@ -104,7 +106,9 @@ describe("getCoachSystemPrompt — DE", () => {
|
||||
expect(prompt).toMatch(/2\. Werte gehören in den Evidenz-Block\./);
|
||||
expect(prompt).toMatch(/3\. Fehlende Daten sind eine Einladung/);
|
||||
expect(prompt).toMatch(/4\. Zurückhaltende Sprache\./);
|
||||
expect(prompt).toMatch(/5\. Mikro-Moves aus dem Motivational Interviewing\./);
|
||||
expect(prompt).toMatch(
|
||||
/5\. Mikro-Moves aus dem Motivational Interviewing\./,
|
||||
);
|
||||
expect(prompt).toMatch(/6\. Off-topic-Eingaben elegant umlenken\./);
|
||||
expect(prompt).toMatch(/7\. Verankere jede Zahl im SNAPSHOT\./);
|
||||
});
|
||||
|
||||
@@ -133,9 +133,8 @@ describe("session lifecycle (real Postgres)", () => {
|
||||
});
|
||||
|
||||
it("destroySession clears the hl_onboarding cookie alongside the session cookie", async () => {
|
||||
const { createSession, destroySession } = await import(
|
||||
"@/lib/auth/session"
|
||||
);
|
||||
const { createSession, destroySession } =
|
||||
await import("@/lib/auth/session");
|
||||
const user = await getPrismaClient().user.create({
|
||||
data: { username: "dest", email: "dest@example.test" },
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user