Skip to content

Commit fa8e188

Browse files
Bill Leoutsakoscursoragent
authored andcommitted
Clarify authorization readiness states
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 4b5d90a commit fa8e188

3 files changed

Lines changed: 23 additions & 5 deletions

File tree

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-sidebar/settings-sidebar.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ export function SettingsSidebar({
7575
const forkingAvailable = useForkingAvailable(workspaceId)
7676
const { userPermissions } = useWorkspacePermissionsContext()
7777
const { canAdmin: canAdminWorkspace } = userPermissions
78-
const permissionsReadinessBusy = userPermissions.isLoading || !userPermissions.canRead
78+
const authorizationState = userPermissions.isLoading
79+
? 'loading'
80+
: userPermissions.canRead
81+
? 'granted'
82+
: 'denied'
7983

8084
const userId = session?.user?.id
8185

@@ -290,7 +294,8 @@ export function SettingsSidebar({
290294
<div
291295
role='navigation'
292296
aria-label='Workspace settings sections'
293-
aria-busy={permissionsReadinessBusy}
297+
aria-busy={authorizationState === 'loading'}
298+
data-authorization-state={authorizationState}
294299
ref={isCollapsed ? undefined : scrollContainerRef}
295300
className={cn(
296301
'flex flex-1 flex-col overflow-y-auto overflow-x-hidden border-t pt-1.5 transition-colors duration-150',

apps/sim/e2e/settings/authorization/contract-integrity.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,17 @@ test('mutation contracts declare every required section and role boundary', () =
227227
pathTemplate.endsWith('/settings/access-control')
228228
)
229229
).toBe(true)
230+
231+
expect(
232+
mutationControlCases
233+
.filter(
234+
({ pathTemplate, controls }) =>
235+
pathTemplate.startsWith('/organization/') &&
236+
controls.some(({ expectation }) => expectation === 'absent')
237+
)
238+
.map(({ caseId }) => caseId),
239+
'organization absence probes must use the Members readiness barrier'
240+
).toEqual(['organization-member-members-controls'])
230241
})
231242

232243
test('Step 4 paths stay canonical and separate from Step 3 special paths', () => {

apps/sim/e2e/settings/authorization/mutation-controls.spec.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,14 @@ async function expectAuthorizationReadiness(
143143
async function expectMutationPermissionsReady(page: Page, pathTemplate: string): Promise<void> {
144144
if (pathTemplate.startsWith('/workspace/')) {
145145
const sidebar = page.getByRole('complementary', { name: 'Workspace sidebar' })
146-
await expect(
147-
sidebar.getByRole('navigation', { name: 'Workspace settings sections' })
148-
).toHaveAttribute('aria-busy', 'false')
146+
const navigation = sidebar.getByRole('navigation', { name: 'Workspace settings sections' })
147+
await expect(navigation).toHaveAttribute('aria-busy', 'false')
148+
await expect(navigation).toHaveAttribute('data-authorization-state', 'granted')
149149
return
150150
}
151151

152+
// Members is the only organization route with an absent-control probe; the
153+
// integrity spec requires any future organization absence case to add a barrier.
152154
if (pathTemplate.endsWith('/settings/members')) {
153155
await expect(page.getByRole('region', { name: 'Organization members' })).toHaveAttribute(
154156
'aria-busy',

0 commit comments

Comments
 (0)