Files
orca/mobile/src/session/QuickCommandsList.test.ts
T
Jinjing 9b79cc1b9e Add copy button for quick command (#13768)
* Add copy button to quick commands with visual feedback

Quick command rows now display a copy button that copies the command body to clipboard. The button shows brief visual feedback ("Copied" or "Couldn't copy") and is disabled when the command body is empty. Includes desktop and mobile UI, tests, and full i18n support.

* fix(ci): unblock verify for quick-command copy button

Key feedback to the copied body so prop changes drop stale labels without
setState-in-effect, and mock expo-clipboard in the mobile list test.
2026-08-11 01:06:03 -07:00

92 lines
2.4 KiB
TypeScript

import { createElement } from 'react'
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { QUICK_COMMAND_SEARCH_QUERY_MAX_LENGTH, QuickCommandsList } from './QuickCommandsList'
vi.mock('react-native', () => ({
ActivityIndicator: 'ActivityIndicator',
Pressable: 'Pressable',
StyleSheet: {
create: <T>(styles: T) => styles,
hairlineWidth: 1
},
Text: 'Text',
TextInput: 'TextInput',
View: 'View'
}))
vi.mock('lucide-react-native', () => ({
Check: 'Check',
Copy: 'Copy',
Pencil: 'Pencil',
Play: 'Play',
Plus: 'Plus',
Search: 'Search',
Trash2: 'Trash2'
}))
vi.mock('expo-clipboard', () => ({ setStringAsync: vi.fn() }))
vi.mock('../components/MobileAgentIcon', () => ({ MobileAgentIcon: 'MobileAgentIcon' }))
describe('QuickCommandsList search', () => {
let renderer: ReactTestRenderer | null = null
beforeEach(() => {})
afterEach(() => {
act(() => renderer?.unmount())
renderer = null
})
it('keeps an active filter clearable when only one command remains', async () => {
await act(async () => {
renderer = create(
createElement(QuickCommandsList, {
repoCommands: [],
globalCommands: [],
totalCount: 1,
query: 'missing',
loading: false,
disabled: false,
canAdd: true,
error: null,
onQueryChange: vi.fn(),
onLaunch: vi.fn(),
onEdit: vi.fn(),
onDelete: vi.fn(),
onAdd: vi.fn()
})
)
})
const search = renderer!.root.findByType('TextInput')
expect(search.props.value).toBe('missing')
expect(search.props.maxLength).toBe(QUICK_COMMAND_SEARCH_QUERY_MAX_LENGTH)
})
it('omits idle search chrome for a single command', async () => {
await act(async () => {
renderer = create(
createElement(QuickCommandsList, {
repoCommands: [],
globalCommands: [],
totalCount: 1,
query: '',
loading: false,
disabled: false,
canAdd: true,
error: null,
onQueryChange: vi.fn(),
onLaunch: vi.fn(),
onEdit: vi.fn(),
onDelete: vi.fn(),
onAdd: vi.fn()
})
)
})
expect(renderer!.root.findAllByType('TextInput')).toHaveLength(0)
})
})