diff --git a/e2e/v137-sharing-managed-profiles.spec.ts b/e2e/v137-sharing-managed-profiles.spec.ts index a97bc38ae..8546db512 100644 --- a/e2e/v137-sharing-managed-profiles.spec.ts +++ b/e2e/v137-sharing-managed-profiles.spec.ts @@ -8,4 +8,18 @@ test.describe("sharing release journey anchors", () => { expect(journey.contract).toBe("inventory-only"); }); } + + test("adult levels and lifecycle", () => { + const adultJourneyNames = RELEASE_JOURNEYS.filter((journey) => + [ + "adult-full-read-scoped-read-write-and-manage", + "manage-mutation-activity-and-fenced-settings", + ].includes(journey.name), + ).map((journey) => journey.name); + + expect(adultJourneyNames).toEqual([ + "adult-full-read-scoped-read-write-and-manage", + "manage-mutation-activity-and-fenced-settings", + ]); + }); }); diff --git a/src/__tests__/shared-record-navigation.test.tsx b/src/__tests__/shared-record-navigation.test.tsx index df014f4f5..baed20fed 100644 --- a/src/__tests__/shared-record-navigation.test.tsx +++ b/src/__tests__/shared-record-navigation.test.tsx @@ -9,6 +9,7 @@ import { isDestinationInSharedRecord, visibleNavDestinations, } from "@/components/layout/nav-model"; +import { resolveRecordPresentation } from "@/lib/navigation/record-presentation"; describe("shared-record navigation", () => { it("keeps every granted route family in one closed eight-domain inventory", () => { @@ -55,4 +56,35 @@ describe("shared-record navigation", () => { expect(navigation.allowsPath("/settings/account")).toBe(false); expect(navigation.allowsPath("/new-unclassified-route")).toBe(false); }); + + it("keeps server-resolved access and record kind distinct in chrome", () => { + expect( + resolveRecordPresentation({ + level: "read", + canWrite: false, + recordKind: "shared", + }), + ).toEqual({ access: "view", recordKind: "shared" }); + expect( + resolveRecordPresentation({ + level: "write", + canWrite: true, + recordKind: "shared", + }), + ).toEqual({ access: "view-and-add", recordKind: "shared" }); + expect( + resolveRecordPresentation({ + level: "manage", + canWrite: true, + recordKind: "shared", + }), + ).toEqual({ access: "manage", recordKind: "shared" }); + expect( + resolveRecordPresentation({ + level: "manage", + canWrite: true, + recordKind: "managed", + }), + ).toEqual({ access: "manage", recordKind: "managed" }); + }); }); diff --git a/src/components/dashboard/__tests__/looking-after-card.test.tsx b/src/components/dashboard/__tests__/looking-after-card.test.tsx index 9cfe7e1f2..196ca6620 100644 --- a/src/components/dashboard/__tests__/looking-after-card.test.tsx +++ b/src/components/dashboard/__tests__/looking-after-card.test.tsx @@ -40,6 +40,16 @@ const FATHER = { recordKind: "shared" as const, canWrite: true, }; +const MANAGED_PROFILE = { + accountId: "managed-profile", + username: "managed-profile", + displayName: "Managed profile", + access: "write" as const, + level: "manage" as const, + sections: null, + recordKind: "managed" as const, + canWrite: true, +}; const mockAccessRef: { value: AccountAccess } = { value: { accounts: [], active: null, canSwitch: false }, @@ -130,6 +140,19 @@ describe("", () => { expect(html).not.toContain("Can view and add"); }); + it("keeps MANAGE and managed profile labels separate", () => { + const html = render({ + accounts: [MANAGED_PROFILE], + active: null, + canSwitch: true, + }); + + expect(html).toContain('data-access-level="manage"'); + expect(html).toContain('data-record-kind="managed"'); + expect(html).toContain("Can read the record, add to it, and change"); + expect(html).toContain("Managed profile"); + }); + it("shows no health data, only a doorway", () => { const html = render({ accounts: [GRANDMOTHER], diff --git a/src/components/layout/__tests__/shared-record-chrome.test.tsx b/src/components/layout/__tests__/shared-record-chrome.test.tsx index a6c8a9651..b2fbd65ca 100644 --- a/src/components/layout/__tests__/shared-record-chrome.test.tsx +++ b/src/components/layout/__tests__/shared-record-chrome.test.tsx @@ -134,6 +134,31 @@ describe("", () => { expect(html).not.toContain("read it, not change it"); }); + it("names MANAGE and a managed profile without reducing either to add access", () => { + const managedProfile = { + ...OWNER, + accountId: "managed-profile", + access: "write" as const, + level: "manage" as const, + recordKind: "managed" as const, + canWrite: true, + }; + const html = render( + { + accounts: [managedProfile], + active: managedProfile, + canSwitch: true, + }, + , + ); + + expect(html).toContain('data-access-level="manage"'); + expect(html).toContain('data-record-kind="managed"'); + expect(html).toContain("Managed profile"); + expect(html).toContain("change or remove what is in it"); + expect(html).not.toContain("add to it, but not change"); + }); + it("uses the warning register, not a subtle tint", () => { // Somebody who stops noticing the banner logs their own reading into // another person's record. The visual register is part of the contract.