Files
supabase/apps/studio/tests/components/SQLEditor/RoleImpersonationSelector.utils.test.ts
Saxon Fletcher 9718eea593 refine role impersonation popover (#49467)
**Old**
<img width="979" height="839" alt="image"
src="https://github.com/user-attachments/assets/7239604f-a37f-483c-84eb-dbafabdeb73c"
/>

**New**
<img width="1185" height="645" alt="image"
src="https://github.com/user-attachments/assets/e699d75f-fd04-47dc-a8da-97f880e39796"
/>


## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Studio UI refinement. This is PR 2 of 2 and depends on #49466.

## What is the current behavior?

The Run SQL query as a role submenu uses the full role-impersonation
card layout, making the nested popover substantially larger than the
surrounding query controls.

## What is the new behavior?

- Adds a compact role-impersonation presentation used only by the query
submenu.
- Uses horizontal FormItemLayout rows and base ToggleGroup, InputGroup,
Input, and Button components.
- Keeps role choices stacked while using tiny controls for user source,
user lookup, external-user fields, and MFA level.
- Keeps authenticated-user controls visible but disabled for Postgres
and Anonymous roles.
- Preserves project-user search, external-user claims, impersonation,
and stop-impersonating behavior.
- Leaves existing role selectors in GraphQL, Table Editor, Realtime, and
other surfaces unchanged.

## Verification

- Focused compact role-selector test
- Studio, UI, and UI Patterns typechecks
- Existing focused Toggle and MultiSelector tests
- Studio ESLint
- Local visual and interaction verification against the supplied
prototype



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **New Features**
* Redesigned role impersonation with role-specific summaries and native
role icons.
* Added native and external user impersonation, including user-source
switching and MFA controls.
* Added user search, external user ID entry, and clearer active-user
controls with accessible labels.

* **Bug Fixes**
* Improved role switching, impersonation clearing, pending selections,
and error recovery.

* **Tests**
* Expanded coverage for role selection, user impersonation, MFA updates,
state transitions, and error handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-08-26 16:28:02 +08:00

75 lines
2.0 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
getRoleSelectionUpdate,
getSelectedRoleOption,
} from '@/components/interfaces/RoleImpersonationSelector/RoleImpersonationSelector.utils'
import type { ImpersonationRole, PostgrestRole } from '@/lib/role-impersonation'
describe('getSelectedRoleOption', () => {
const cases: Array<{
name: string
role: ImpersonationRole | undefined
expected: PostgrestRole
}> = [
{ name: 'defaults to Postgres when no role is set', role: undefined, expected: 'service_role' },
{
name: 'maps the service role to Postgres',
role: { type: 'postgrest', role: 'service_role' },
expected: 'service_role',
},
{
name: 'maps custom roles to Postgres',
role: { type: 'custom', role: 'reporter' },
expected: 'service_role',
},
{
name: 'preserves the anonymous role',
role: { type: 'postgrest', role: 'anon' },
expected: 'anon',
},
{
name: 'preserves native authenticated roles',
role: {
type: 'postgrest',
role: 'authenticated',
userType: 'native',
},
expected: 'authenticated',
},
{
name: 'preserves external authenticated roles',
role: {
type: 'postgrest',
role: 'authenticated',
userType: 'external',
},
expected: 'authenticated',
},
]
it.each(cases)('$name', ({ role, expected }) => {
expect(getSelectedRoleOption(role)).toBe(expected)
})
})
describe('getRoleSelectionUpdate', () => {
it('clears role impersonation for Postgres', () => {
expect(getRoleSelectionUpdate('service_role')).toEqual({
shouldSetRole: true,
role: undefined,
})
})
it('sets the anonymous PostgREST role', () => {
expect(getRoleSelectionUpdate('anon')).toEqual({
shouldSetRole: true,
role: { type: 'postgrest', role: 'anon' },
})
})
it('waits for a user selection before setting the authenticated role', () => {
expect(getRoleSelectionUpdate('authenticated')).toEqual({ shouldSetRole: false })
})
})