History

Fix self-host live-role scenario

Rhys Sullivan committed 2 months ago

Commit ea31cbe1 parent 0bd654a1 file · +23 −6Browse files

Unified · Split

e2e/selfhost/mcp-browser-approval-live-role.test.ts+23−6
@@ -26,6 +26,7 @@ return JSON.stringify(result); · 25 unmodified lines
26 26
27interface MemberRow {27interface MemberRow {
28 readonly id: string;28 readonly id: string;
29 readonly userId: string;
29 readonly email: string;30 readonly email: string;
30 readonly role: string;31 readonly role: string;
31}32}
@@ -52,11 +53,11 @@ scenario( · 20 unmodified lines
52 const target = yield* Target;53 const target = yield* Target;
53 const api = yield* Api;54 const api = yield* Api;
54 const mcp = yield* Mcp;55 const mcp = yield* Mcp;
55 const actor = yield* target.newIdentity();56 const controller = yield* target.newIdentity();
56 const controller = yield* Effect.promise(() =>57 const actor = yield* Effect.promise(() =>
57 createInvitedIdentity(target.baseUrl, actor, {58 createInvitedIdentity(target.baseUrl, controller, {
58 role: "admin",59 role: "admin",
59 emailPrefix: "approval-role-controller",60 emailPrefix: "approval-role-actor",
60 }),61 }),
61 );62 );
62 const controllerCookie = controller.headers?.cookie;63 const controllerCookie = controller.headers?.cookie;
@@ -81,11 +82,22 @@ scenario( · 18 unmodified lines
81 );82 );
82 const actorMember = membersBody.members.find((member) => member.email === actor.label);83 const actorMember = membersBody.members.find((member) => member.email === actor.label);
83 expect(84 expect(
84 actorMember?.role === "owner" || actorMember?.role === "admin",85 actorMember?.role === "admin",
85 "the actor begins with privileged organization membership",86 "the actor begins with privileged organization membership",
86 ).toBe(true);87 ).toBe(true);
87 if (!actorMember) return yield* Effect.die("the actor membership was not listed");88 if (!actorMember) return yield* Effect.die("the actor membership was not listed");
88 89
90 const setGlobalRole = (role: "admin" | "user"): Effect.Effect<Response> =>
91 Effect.promise(() =>
92 accountRequest(target.baseUrl, controllerCookie, "/api/auth/admin/set-role", {
93 method: "POST",
94 headers: { "content-type": "application/json" },
95 body: JSON.stringify({ userId: actorMember.userId, role }),
96 }),
97 );
98 const promoted = yield* setGlobalRole("admin");
99 expect(promoted.status, "the actor has a stale global admin role to distrust").toBe(200);
100
89 const setRole = (roleSlug: "admin" | "member"): Effect.Effect<Response> =>101 const setRole = (roleSlug: "admin" | "member"): Effect.Effect<Response> =>
90 Effect.promise(() =>102 Effect.promise(() =>
91 accountRequest(103 accountRequest(
@@ -134,7 +146,11 @@ scenario( · 42 unmodified lines
134 );146 );
135 147
136 expect(decision.status, "the browser decision reaches the paused execution").toBe(200);148 expect(decision.status, "the browser decision reaches the paused execution").toBe(200);
137 expect(resumed.ok, "the resumed workspace mutation is denied at the sink").toBe(false);149 expect(resumed.ok, "the resumed sandbox reports the tool result normally").toBe(true);
150 expect(
151 resumed.text,
152 "the resumed workspace mutation preserves the workspace-admin denial",
153 ).toMatch(/OrgWriteDenied|administrator|admin/i);
138 const policies = yield* actorClient.policies.list();154 const policies = yield* actorClient.policies.list();
139 expect(155 expect(
140 policies.some((policy) => policy.pattern === CREATED_PATTERN),156 policies.some((policy) => policy.pattern === CREATED_PATTERN),
@@ -149,6 +165,7 @@ scenario( · 8 unmodified lines
149 payload: { owner: "org" },165 payload: { owner: "org" },
150 }),166 }),
151 ),167 ),
168 Effect.andThen(setGlobalRole("user")),
152 Effect.ignore,169 Effect.ignore,
153 ),170 ),
154 ),171 ),