mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import {
|
|
installChatViewHooks,
|
|
assistantTurn,
|
|
listIds,
|
|
render,
|
|
renderedRow,
|
|
update
|
|
} from './MobileNativeChatView.harness.test-fixture'
|
|
|
|
vi.mock('react-native', async () => {
|
|
const { reactNativeStub } = await import('./MobileNativeChatView.render-stubs.test-fixture')
|
|
return reactNativeStub()
|
|
})
|
|
vi.mock('react-native-safe-area-context', () => ({
|
|
useSafeAreaInsets: () => ({ top: 0, bottom: 0, left: 0, right: 0 })
|
|
}))
|
|
vi.mock('react-native-gesture-handler', async () => {
|
|
const { gestureHandlerStub } = await import('./MobileNativeChatView.render-stubs.test-fixture')
|
|
return gestureHandlerStub()
|
|
})
|
|
vi.mock('lucide-react-native', () => ({
|
|
ArrowDown: 'ArrowDown',
|
|
ChevronsDownUp: 'ChevronsDownUp',
|
|
ChevronsUpDown: 'ChevronsUpDown',
|
|
Square: 'Square'
|
|
}))
|
|
vi.mock('./MobileNativeChatMessage', () => ({ MobileNativeChatMessage: 'ChatMessage' }))
|
|
vi.mock('./MobileNativeChatLiveLine', () => ({ MobileNativeChatLiveLine: 'LiveStatus' }))
|
|
vi.mock('./MobileNativeChatAsk', () => ({ MobileNativeChatAsk: 'ChatAsk' }))
|
|
vi.mock('./MobileNativeChatPermission', () => ({ MobileNativeChatPermission: 'ChatPermission' }))
|
|
vi.mock('./MobileNativeChatQuestion', () => ({ MobileNativeChatQuestion: 'ChatQuestion' }))
|
|
vi.mock('../components/ActionSheetModal', () => ({ ActionSheetModal: 'ActionSheetModal' }))
|
|
vi.mock('./native-chat/composer/MobileNativeChatComposer', async () => {
|
|
const { composerStub } = await import('./MobileNativeChatView.render-stubs.test-fixture')
|
|
return composerStub()
|
|
})
|
|
|
|
describe('MobileNativeChatView: rows and the streaming bubble', () => {
|
|
installChatViewHooks()
|
|
|
|
// Streaming eligibility is tested in the overlay, which stays mounted across chat-view toggles.
|
|
it('appends the gated streaming bubble after the folded transcript', async () => {
|
|
const folded = [assistantTurn('a1', 'The tests pass.')]
|
|
await render({ folded })
|
|
expect(listIds()).toEqual(['a1'])
|
|
|
|
await update({ folded, streaming: 'The tests' })
|
|
|
|
expect(listIds()).toEqual(['a1', 'streaming'])
|
|
})
|
|
|
|
it('tells a row whether the host still waits on the prompt it stands for', async () => {
|
|
const rows = [assistantTurn('asked', 'Tea or coffee?'), assistantTurn('open', 'Which branch?')]
|
|
await render({ messages: rows, folded: rows, actionablePromptIds: ['open'] })
|
|
expect(renderedRow('asked').props.awaiting).toBe(false)
|
|
expect(renderedRow('open').props.awaiting).toBe(true)
|
|
})
|
|
|
|
it('renders an accepted optimistic image send without a queued state', async () => {
|
|
await render({
|
|
pending: [{ id: 'pending-1', text: 'look', images: ['file:///phone-photo.jpg'] }]
|
|
})
|
|
|
|
expect(listIds()).toEqual(['pending-1'])
|
|
expect(renderedRow('pending-1').props).not.toHaveProperty('queued')
|
|
})
|
|
})
|