mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
fix(settings): gate the Coach tuning on the record's module state
Settings → Coach hid its preference and nudge cards on the raw disableCoach column, which /me publishes for the signed-in person. Inside a managed or shared record that answered for the wrong person: a guardian with the Coach on saw the tuning for a record that has it off, and the other way round. The cards now read the module map the server resolves for the record on screen, the same map the navigation and the settings entry already follow.
This commit is contained in:
1 parent
eae46ed535
commit
fdbbd3a84a
4 files changed
+56
-9
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;
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user