feat(permission): add new-session default setting
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
// @vitest-environment jsdom
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { bindSnapshotSelector } from '@deepseek-ai/dsh-client-web-react'
|
||||
import type { SettingsNamespaceView } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import { PermissionRow, type PermissionRowProps } from '../src/client/PermissionRow.tsx'
|
||||
import { en } from '../src/client/locales.ts'
|
||||
import { PermissionSettingsController } from '../src/client/settings-store.ts'
|
||||
|
||||
afterEach(cleanup)
|
||||
|
||||
const SCHEMA = {
|
||||
uid: 4,
|
||||
refs: {
|
||||
1: { type: 'const', value: 'read-only' },
|
||||
2: { type: 'const', value: 'workspace-write' },
|
||||
3: { type: 'union', list: [1, 2] },
|
||||
4: { type: 'object', dict: { defaultPreset: 3 } },
|
||||
},
|
||||
}
|
||||
|
||||
function view(defaultPreset: string, revision = 0): SettingsNamespaceView {
|
||||
return {
|
||||
ns: 'permission',
|
||||
schema: SCHEMA,
|
||||
value: { defaultPreset },
|
||||
base: { defaultPreset: 'read-only' },
|
||||
applies: 'live',
|
||||
secrets: [],
|
||||
revision,
|
||||
}
|
||||
}
|
||||
|
||||
function ok<T>(value: T) {
|
||||
return { rpcId: 'test', result: { ok: true as const, value } }
|
||||
}
|
||||
|
||||
const dictionary: Record<string, string> = en
|
||||
const t: PermissionRowProps['t'] = key => dictionary[key] ?? key
|
||||
const runtime = {
|
||||
useSessions: (() => { throw new Error('unused') }) as never,
|
||||
useWorkspaces: (() => { throw new Error('unused') }) as never,
|
||||
}
|
||||
|
||||
function mount(controller: PermissionSettingsController) {
|
||||
return render(
|
||||
<PermissionRow
|
||||
{...runtime}
|
||||
controller={controller}
|
||||
useSnapshot={bindSnapshotSelector(controller.store)}
|
||||
t={t}
|
||||
/>,
|
||||
)
|
||||
}
|
||||
|
||||
describe('PermissionRow', () => {
|
||||
it('loads the descriptor, opens the menu, and selects a new default', async () => {
|
||||
const mutate = vi.fn(() => Promise.resolve(ok(view('workspace-write', 1))))
|
||||
const controller = new PermissionSettingsController({
|
||||
settings: {
|
||||
describe: () => Promise.resolve(ok({ writable: true, namespaces: [view('read-only')] })),
|
||||
mutate,
|
||||
} as never,
|
||||
})
|
||||
mount(controller)
|
||||
const button = await screen.findByRole('button', { name: 'Read Only' })
|
||||
expect(button.getAttribute('aria-expanded')).toBe('false')
|
||||
fireEvent.click(button)
|
||||
expect(button.getAttribute('aria-expanded')).toBe('true')
|
||||
fireEvent.keyDown(document, { key: 'Escape' })
|
||||
await waitFor(() => { expect(button.getAttribute('aria-expanded')).toBe('false') })
|
||||
fireEvent.click(button)
|
||||
fireEvent.click(button)
|
||||
expect(button.getAttribute('aria-expanded')).toBe('false')
|
||||
fireEvent.click(button)
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: 'Workspace Write' }))
|
||||
await screen.findByRole('button', { name: 'Workspace Write' })
|
||||
expect(mutate).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('hides an unavailable namespace and disables a read-only provider', async () => {
|
||||
const absent = new PermissionSettingsController({
|
||||
settings: {
|
||||
describe: () => Promise.resolve(ok({ writable: true, namespaces: [] })),
|
||||
mutate: vi.fn(),
|
||||
} as never,
|
||||
})
|
||||
const rendered = mount(absent)
|
||||
await waitFor(() => { expect(rendered.container.textContent).toBe('') })
|
||||
rendered.unmount()
|
||||
|
||||
const readonly = new PermissionSettingsController({
|
||||
settings: {
|
||||
describe: () => Promise.resolve(ok({ writable: false, namespaces: [view('read-only')] })),
|
||||
mutate: vi.fn(),
|
||||
} as never,
|
||||
})
|
||||
mount(readonly)
|
||||
expect((await screen.findByRole('button', { name: 'Read Only' })).hasAttribute('disabled')).toBe(true)
|
||||
})
|
||||
|
||||
it('shows loading and a contained write error', async () => {
|
||||
const describe = Promise.withResolvers<ReturnType<typeof ok<{
|
||||
writable: boolean
|
||||
namespaces: SettingsNamespaceView[]
|
||||
}>>>()
|
||||
const controller = new PermissionSettingsController({
|
||||
settings: {
|
||||
describe: () => describe.promise,
|
||||
mutate: () => Promise.resolve({
|
||||
rpcId: 'test',
|
||||
result: {
|
||||
ok: false as const,
|
||||
error: { code: 'settings-conflict', message: 'changed elsewhere', details: {} },
|
||||
},
|
||||
}),
|
||||
} as never,
|
||||
})
|
||||
mount(controller)
|
||||
expect((await screen.findByRole('button', { name: 'Loading' })).hasAttribute('disabled')).toBe(true)
|
||||
describe.resolve(ok({ writable: true, namespaces: [view('read-only')] }))
|
||||
const button = await screen.findByRole('button', { name: 'Read Only' })
|
||||
fireEvent.click(button)
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: 'Workspace Write' }))
|
||||
expect((await screen.findByRole('alert')).textContent).toBe('changed elsewhere')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user