Merge remote-tracking branch 'origin/main' into fix/v1397-tz

This commit is contained in:
Marc-André Bombeck committed 2026-10-01 10:59:51 +02:00
commit ada490c7e9
57 files changed
+1485 -99

No files matched your search

@@ -24,6 +24,8 @@ vi.mock("@/hooks/use-auth", () => ({
role: "USER",
timezone: "Europe/Berlin",
disableCoach: authState.disableCoach,
// The server's module map mirrors the record's opt-out.
modules: { coach: !authState.disableCoach },
},
isAuthenticated: true,
isLoading: false,
@@ -34,6 +34,8 @@ vi.mock("@/hooks/use-auth", () => ({
role: "USER",
timezone: "Europe/Berlin",
disableCoach: !coach.available,
// The record's module map, which the section's gate reads.
modules: { coach: coach.available },
},
isAuthenticated: true,
isLoading: false,
@@ -14,6 +14,13 @@ vi.mock("next/navigation", () => ({
usePathname: () => "/settings/coach",
}));
// Past hydration only where a test says so: the gate reads the account once
// mounted, and the pre-hydration pass shows every card.
const mountState = { mounted: false };
vi.mock("@/hooks/use-mounted", () => ({
useMounted: () => mountState.mounted,
}));
vi.mock("@tanstack/react-query", () => ({
useQuery: () => ({ data: null, isLoading: false, refetch: vi.fn() }),
useInfiniteQuery: () => ({ data: undefined, isLoading: false }),
@@ -31,10 +38,18 @@ vi.mock("@/hooks/use-ai-capability", () => ({
}),
}));
const authState: { disableCoach: boolean } = { disableCoach: false };
const authState: {
disableCoach: boolean;
modules: { coach?: boolean } | undefined;
} = { disableCoach: false, modules: undefined };
vi.mock("@/hooks/use-auth", () => ({
useAuth: () => ({
user: { id: "u1", role: "USER", disableCoach: authState.disableCoach },
user: {
id: "u1",
role: "USER",
disableCoach: authState.disableCoach,
modules: authState.modules,
},
isAuthenticated: true,
isLoading: false,
refetch: vi.fn(),
@@ -83,3 +98,24 @@ describe("<CoachSection> — SSR smoke", () => {
expect(html).not.toContain("settings.coach.activate.");
});
});
describe("<CoachSection> — the tuning follows the record, not the account", () => {
it("hides the nudge when the record has the Coach off, whatever the viewer's own opt-out says", () => {
// A guardian with the Coach on, inside a managed record that has it off:
// `/me` publishes the viewer's own `disableCoach` and the RECORD's module
// map. The record's answer decides.
mountState.mounted = true;
authState.disableCoach = false;
authState.modules = { coach: false };
try {
expect(render()).not.toContain('id="coach-nudge"');
authState.disableCoach = true;
authState.modules = { coach: true };
expect(render()).toContain('id="coach-nudge"');
} finally {
mountState.mounted = false;
authState.disableCoach = false;
authState.modules = undefined;
}
});
});