mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
test(client): cover menu dismiss, goal pause, and permission label paths
Close the per-file coverage gaps the new UI behavior introduced: MenuView pointer-outside dismiss (all guard branches), the GoalBar pause action, the ui-slash injected onDismiss face, and the non-kebab permission name passthrough.
This commit is contained in:
@@ -104,6 +104,13 @@ describe('GoalBar', () => {
|
||||
expect(screen.getByRole('textbox', { name: 'Goal objective' })).toBeTruthy()
|
||||
})
|
||||
|
||||
it('active goal: the pause action pauses', () => {
|
||||
const actions = makeActions()
|
||||
render(<GoalBar goal={makeGoal()} {...actions} />)
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Pause goal' }))
|
||||
expect(actions.onPause).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('paused goal: "Paused Goal" with a resume action before edit', () => {
|
||||
const actions = makeActions()
|
||||
render(<GoalBar goal={makeGoal({ phase: 'paused' })} {...actions} />)
|
||||
|
||||
@@ -85,6 +85,11 @@ describe('ui-permission browser plugin', () => {
|
||||
const again = await c.ui.options(proj, new AbortController().signal)
|
||||
expect(again.find(option => option.id === 'workspace-write')?.active).toBe(true)
|
||||
expect(again.find(option => option.id === 'read-only')?.detail).toBe('Reads only.')
|
||||
// Kebab-case names title-case; non-kebab host-configured names pass through.
|
||||
expect(again.map(option => option.label)).toEqual(['Read Only', 'Workspace Write', 'Danger Full Access'])
|
||||
b.values.set(sid('s1'), { ...SELECT, options: [{ value: 'plain', name: 'Ask Every Time' }] })
|
||||
const passthrough = await c.ui.options(proj, new AbortController().signal)
|
||||
expect(passthrough[0]?.label).toBe('Ask Every Time')
|
||||
// A projection that vanished between availability and open throws.
|
||||
expect(() => c.ui.options({ sessionId: sid('ghost') }, new AbortController().signal))
|
||||
.toThrow(/not available on this host/)
|
||||
|
||||
@@ -84,6 +84,9 @@ describe('apply', () => {
|
||||
// The pick face routes into the controller pipeline (closed menu → no-op).
|
||||
injected.onPick('command', 0)
|
||||
expect(controller.menu.getSnapshot().open).toBe(false)
|
||||
// The dismiss face routes into the controller too (closed menu → no-op).
|
||||
injected.onDismiss()
|
||||
expect(controller.menu.getSnapshot().open).toBe(false)
|
||||
// An unknown session id fails loud (no silent scope miss).
|
||||
expect(() => injectEntry(sid('ghost'))).toThrow(/resolved no scope/)
|
||||
})
|
||||
|
||||
@@ -142,6 +142,48 @@ describe('MenuView', () => {
|
||||
expect(screen.getByRole('listbox').style.maxHeight).toBe('88px')
|
||||
})
|
||||
|
||||
it('pointerdown outside the menu (no composer card ancestor) dismisses', () => {
|
||||
const { onDismiss } = mount(openState())
|
||||
fireEvent.pointerDown(document.body)
|
||||
expect(onDismiss).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('pointerdown inside the list does not dismiss', () => {
|
||||
const { onDismiss } = mount(openState())
|
||||
fireEvent.pointerDown(screen.getAllByRole('option')[0]!)
|
||||
expect(onDismiss).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('pointerdown inside the surrounding composer card does not dismiss; outside it does', () => {
|
||||
const menu = createSnapshotStore<MenuState>(openState())
|
||||
const onDismiss = vi.fn()
|
||||
render(
|
||||
<div data-composer-card="">
|
||||
<MenuView menu={menu} onPick={vi.fn()} onDismiss={onDismiss} t={t} />
|
||||
<button type="button" data-testid="composer-button" />
|
||||
</div>,
|
||||
)
|
||||
fireEvent.pointerDown(screen.getByTestId('composer-button'))
|
||||
expect(onDismiss).not.toHaveBeenCalled()
|
||||
fireEvent.pointerDown(document.body)
|
||||
expect(onDismiss).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('ignores a pointerdown whose target is not a DOM node', () => {
|
||||
const { onDismiss } = mount(openState())
|
||||
const ev = new Event('pointerdown', { bubbles: true })
|
||||
Object.defineProperty(ev, 'target', { value: {} })
|
||||
document.dispatchEvent(ev)
|
||||
expect(onDismiss).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('closing the menu removes the dismiss listener', () => {
|
||||
const { menu, onDismiss } = mount(openState())
|
||||
act(() => { menu.set(CLOSED) })
|
||||
fireEvent.pointerDown(document.body)
|
||||
expect(onDismiss).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('mousedown on a row picks (source, index) and prevents the focus steal', () => {
|
||||
const { onPick } = mount(openState())
|
||||
const options = screen.getAllByRole('option')
|
||||
|
||||
Reference in New Issue
Block a user