mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
feat: let the record's module map filter its own navigation
The other half of the switched-payload change, found by the integration test that asserted the door was gone and got the door. `isNavDestinationVisible` short-circuited on `sharedRecord`, so a switched session skipped the module filter entirely and every destination the grant's scope allowed was offered. That was right while the map was the actor's: a delegate's own preferences must not hide a domain the record granted. The map is the record's now, so the objection is gone and the line is what makes a guardian's toggle visible inside the profile it was set for. Scope decides which doors the grant opens; the map decides which of them the record uses at all. The read-only profile summary needs its marker checked against `!sharedRecord` rather than reached through the removed short-circuit, and the case that pinned the old reading is turned round with the reason written out. Refs #939
This commit is contained in:
1 parent
bed2ab568e
commit
ccca056f64
3 files changed
+75
-16
No files matched your search
@@ -89,6 +89,32 @@ describe("the destination list under a switch", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("a module the RECORD does not track", () => {
|
||||
/**
|
||||
* #939 — the map `GET /api/auth/me` publishes is the RECORD's while a
|
||||
* session is switched into one, so this filter is what makes a guardian's
|
||||
* toggle visible. Before it, turning Cycle off for a profile left the Cycle
|
||||
* door standing in that profile's own navigation, and the toggle wrote a
|
||||
* column nothing on screen was reading.
|
||||
*/
|
||||
it("drops its destination inside the record", () => {
|
||||
const withCycle = visibleNavDestinations(ALL_MODULES, true, true, null).map(
|
||||
(d) => d.href,
|
||||
);
|
||||
expect(withCycle).toContain("/cycle");
|
||||
|
||||
const withoutCycle = visibleNavDestinations(
|
||||
{ ...ALL_MODULES, cycle: false },
|
||||
true,
|
||||
true,
|
||||
null,
|
||||
).map((d) => d.href);
|
||||
expect(withoutCycle).not.toContain("/cycle");
|
||||
// Only that one door: a module toggle is not a scope change.
|
||||
expect(withoutCycle).toContain("/measurements");
|
||||
});
|
||||
});
|
||||
|
||||
describe("the utility tail under a switch", () => {
|
||||
it("disappears entirely", () => {
|
||||
// Settings holds credentials, integrations, notification channels and
|
||||
|
||||
@@ -342,13 +342,22 @@ function isNavDestinationVisible(
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// A shared record's server-resolved scope decides which health-domain doors
|
||||
// exist. The actor's module preferences describe their own dashboard and
|
||||
// must not hide a domain the target record explicitly granted.
|
||||
if (sharedRecord) return true;
|
||||
if (d.sharedRecordOnly) return false;
|
||||
// The inverse marker: a destination that exists ONLY inside somebody else's
|
||||
// record (the read-only profile summary). Guarded on `!sharedRecord` rather
|
||||
// than reached only through the shared arm, which is what it relied on
|
||||
// before the module gate below started applying to a shared record too.
|
||||
if (!sharedRecord && d.sharedRecordOnly) return false;
|
||||
if (!d.requiresModule) return true;
|
||||
if (!mounted) return false;
|
||||
// The module map, and whose it is, is the whole point. A shared record used
|
||||
// to skip this line: the grant's scope decided which doors existed, and the
|
||||
// module map was the ACTOR's, which describes their own dashboard and must
|
||||
// not hide a domain the record granted. `GET /api/auth/me` now resolves the
|
||||
// map for the RECORD the session is inside (#939), so the objection is gone
|
||||
// and the line is the one that makes a guardian's toggle visible — without
|
||||
// it, turning Cycle off for a profile left the Cycle door standing in that
|
||||
// profile's own navigation. Scope decides which doors the grant opens;
|
||||
// this decides which of them the record tracks at all.
|
||||
return modules?.[d.requiresModule] !== false;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user