mirror of
https://github.com/stablyai/orca.git
synced 2026-09-29 08:03:20 +00:00
test(mobile): drop the collapsed host/shell roundtrip matrices
Each `it.each([[true, true]])` ran a single case while advertising a matrix, and the branches guarded by `host && shell` were dead. Naming the case says what the test proves, and deleting the constant branches leaves only the lane that runs. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
This commit is contained in:
@@ -3,8 +3,8 @@ import { nativeChatBridgeFixture } from './mobile-web-host-native-chat-test-fixt
|
||||
|
||||
afterEach(() => vi.restoreAllMocks())
|
||||
|
||||
async function fixture(host = true, shell = true) {
|
||||
const f = nativeChatBridgeFixture(host, shell)
|
||||
async function fixture() {
|
||||
const f = nativeChatBridgeFixture()
|
||||
const workspaceId = (await f.client.workspaceSnapshot({ limit: 10 })).workspaces[0]!.id
|
||||
const snapshot = await f.client.sessionSnapshot({ workspaceId })
|
||||
const tab = snapshot.tabs.find((tab) => tab.type === 'terminal')!
|
||||
@@ -18,8 +18,8 @@ async function fixture(host = true, shell = true) {
|
||||
}
|
||||
}
|
||||
describe('generic native-chat actions', () => {
|
||||
it.each([[true, true]])('host=%s shell=%s uses a compatible action lane', async (host, shell) => {
|
||||
const f = await fixture(host, shell)
|
||||
it('uses the generic mutate lane instead of terminal.send', async () => {
|
||||
const f = await fixture()
|
||||
const result = await f.client.nativeChat.sendMessage(
|
||||
{ ...f.payload, text: 'hello' },
|
||||
undefined,
|
||||
@@ -28,23 +28,19 @@ describe('generic native-chat actions', () => {
|
||||
expect(result.outcome).toBe('accepted')
|
||||
expect(
|
||||
f.sendRequest.mock.calls.filter(([name]) => name === 'mobileWeb.nativeChat.mutate')
|
||||
).toHaveLength(host && shell ? 1 : 0)
|
||||
expect(f.sendRequest.mock.calls.filter(([name]) => name === 'terminal.send')).toHaveLength(
|
||||
host && shell ? 0 : 1
|
||||
)
|
||||
if (host && shell) {
|
||||
expect(result).toMatchObject({ futureReceipt: { revision: 2 } })
|
||||
const [, params] = f.sendRequest.mock.calls.find(
|
||||
([name]) => name === 'mobileWeb.nativeChat.mutate'
|
||||
)!
|
||||
expect(params).toMatchObject({
|
||||
action: 'sendMessage',
|
||||
text: 'hello',
|
||||
resourceId: 'opaque-resource'
|
||||
})
|
||||
expect(params).not.toHaveProperty('sessionId')
|
||||
expect(params).not.toHaveProperty('deadline')
|
||||
}
|
||||
).toHaveLength(1)
|
||||
expect(f.sendRequest.mock.calls.filter(([name]) => name === 'terminal.send')).toHaveLength(0)
|
||||
expect(result).toMatchObject({ futureReceipt: { revision: 2 } })
|
||||
const [, params] = f.sendRequest.mock.calls.find(
|
||||
([name]) => name === 'mobileWeb.nativeChat.mutate'
|
||||
)!
|
||||
expect(params).toMatchObject({
|
||||
action: 'sendMessage',
|
||||
text: 'hello',
|
||||
resourceId: 'opaque-resource'
|
||||
})
|
||||
expect(params).not.toHaveProperty('sessionId')
|
||||
expect(params).not.toHaveProperty('deadline')
|
||||
f.client.dispose()
|
||||
})
|
||||
it.each(['respond', 'stop', 'prepareCommit'] as const)(
|
||||
|
||||
@@ -4,8 +4,8 @@ import { MOBILE_WEB_BRIDGE_ROUNDTRIP_CONTEXT } from './mobile-web-bridge-roundtr
|
||||
import { nativeChatBridgeFixture as fixture } from './mobile-web-host-native-chat-test-fixture'
|
||||
|
||||
describe('native-chat generic read migration', () => {
|
||||
it.each([[true, true]])('host=%s shell=%s', async (host, shell) => {
|
||||
const f = fixture(host, shell)
|
||||
it('reads native chat through the generic host lane', async () => {
|
||||
const f = fixture()
|
||||
const workspaceId = (await f.client.workspaceSnapshot({ limit: 10 })).workspaces[0]!.id
|
||||
const session = await f.client.sessionSnapshot({ workspaceId })
|
||||
const tab = session.tabs.find((tab) => tab.type === 'terminal')!
|
||||
@@ -17,43 +17,34 @@ describe('native-chat generic read migration', () => {
|
||||
tab.id
|
||||
)
|
||||
expect(result.messages[0].blocks[0]).toMatchObject({ type: 'text', text: 'hello' })
|
||||
if (host && shell) {
|
||||
const pageSession = boundDocument(f)
|
||||
expect(result).toEqual(f.transcript)
|
||||
expect(f.sendRequest).toHaveBeenCalledWith(
|
||||
'mobileWeb.nativeChat.bind',
|
||||
{
|
||||
worktree: 'id:host-workspace',
|
||||
pageSession,
|
||||
tabId: 'tab'
|
||||
},
|
||||
expect.objectContaining({ beforeSend: expect.any(Function) })
|
||||
)
|
||||
expect(f.sendRequest).toHaveBeenCalledWith(
|
||||
'mobileWeb.nativeChat.read',
|
||||
{
|
||||
worktree: 'id:host-workspace',
|
||||
pageSession,
|
||||
resourceId: 'opaque-resource',
|
||||
read: { limit: 20 }
|
||||
},
|
||||
expect.objectContaining({ beforeSend: expect.any(Function) })
|
||||
)
|
||||
expect(f.sendRequest.mock.calls.some(([method]) => method === 'nativeChat.readSession')).toBe(
|
||||
false
|
||||
)
|
||||
} else {
|
||||
expect(
|
||||
f.sendRequest.mock.calls.some(([method]) => method === 'mobileWeb.nativeChat.bind')
|
||||
).toBe(false)
|
||||
expect(f.sendRequest.mock.calls.some(([method]) => method === 'nativeChat.readSession')).toBe(
|
||||
true
|
||||
)
|
||||
}
|
||||
const pageSession = boundDocument(f)
|
||||
expect(result).toEqual(f.transcript)
|
||||
expect(f.sendRequest).toHaveBeenCalledWith(
|
||||
'mobileWeb.nativeChat.bind',
|
||||
{
|
||||
worktree: 'id:host-workspace',
|
||||
pageSession,
|
||||
tabId: 'tab'
|
||||
},
|
||||
expect.objectContaining({ beforeSend: expect.any(Function) })
|
||||
)
|
||||
expect(f.sendRequest).toHaveBeenCalledWith(
|
||||
'mobileWeb.nativeChat.read',
|
||||
{
|
||||
worktree: 'id:host-workspace',
|
||||
pageSession,
|
||||
resourceId: 'opaque-resource',
|
||||
read: { limit: 20 }
|
||||
},
|
||||
expect.objectContaining({ beforeSend: expect.any(Function) })
|
||||
)
|
||||
expect(f.sendRequest.mock.calls.some(([method]) => method === 'nativeChat.readSession')).toBe(
|
||||
false
|
||||
)
|
||||
expect(JSON.stringify(f.shellMessages)).not.toContain('private-session')
|
||||
})
|
||||
it.each([[true, true]])('stream host=%s shell=%s', async (host, shell) => {
|
||||
const f = fixture(host, shell)
|
||||
it('streams native chat through the generic host lane', async () => {
|
||||
const f = fixture()
|
||||
const workspaceId = (await f.client.workspaceSnapshot({ limit: 10 })).workspaces[0]!.id
|
||||
const session = await f.client.sessionSnapshot({ workspaceId })
|
||||
const tab = session.tabs[0]
|
||||
@@ -68,21 +59,15 @@ describe('native-chat generic read migration', () => {
|
||||
vi.fn()
|
||||
)
|
||||
await subscription.ready
|
||||
const generic = host && shell
|
||||
expect(f.subscribe.mock.calls[0][0]).toBe(
|
||||
generic ? 'mobileWeb.nativeChat.subscribe' : 'nativeChat.subscribe'
|
||||
)
|
||||
expect(f.subscribe.mock.calls[0][0]).toBe('mobileWeb.nativeChat.subscribe')
|
||||
const event = { type: 'snapshot', ...f.transcript }
|
||||
f.emit(event)
|
||||
await vi.waitFor(() => expect(onEvent).toHaveBeenCalledOnce())
|
||||
if (generic) {
|
||||
const pageSession = boundDocument(f)
|
||||
expect(onEvent).toHaveBeenCalledWith(event)
|
||||
expect(f.subscribe.mock.calls[0][1]).toMatchObject({
|
||||
pageSession,
|
||||
resourceId: 'opaque-resource'
|
||||
})
|
||||
}
|
||||
expect(onEvent).toHaveBeenCalledWith(event)
|
||||
expect(f.subscribe.mock.calls[0][1]).toMatchObject({
|
||||
pageSession: boundDocument(f),
|
||||
resourceId: 'opaque-resource'
|
||||
})
|
||||
subscription.unsubscribe()
|
||||
expect(f.unsubscribe).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { RpcClient } from '../transport/rpc-client'
|
||||
import { createMobileWebBridgeRoundtripFixture } from './mobile-web-bridge-roundtrip-fixture'
|
||||
import { MOBILE_WEB_PRODUCTION_GRANTS } from './mobile-web-production-grants'
|
||||
|
||||
function fixture(catalogAvailable = true, genericShell = true) {
|
||||
function fixture() {
|
||||
let emit: (event: unknown) => void = () => {}
|
||||
const unsubscribe = vi.fn()
|
||||
const subscribe = vi.fn<RpcClient['subscribe']>((_method, _params, listener) => {
|
||||
@@ -21,44 +21,40 @@ function fixture(catalogAvailable = true, genericShell = true) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return catalogAvailable
|
||||
? {
|
||||
ok: true,
|
||||
result: {
|
||||
grants: [
|
||||
{
|
||||
method: 'mobileWeb.files.watch',
|
||||
mode: 'subscription',
|
||||
workspaceParam: 'worktree',
|
||||
unsubscribeMethod: 'files.unwatch',
|
||||
maxRequestBytes: 1024,
|
||||
maxResponseBytes: 512 * 1024
|
||||
},
|
||||
{
|
||||
method: 'future.events',
|
||||
mode: 'subscription',
|
||||
workspaceParam: 'scope',
|
||||
unsubscribeMethod: 'future.release',
|
||||
maxRequestBytes: 1024,
|
||||
maxResponseBytes: 512 * 1024
|
||||
}
|
||||
]
|
||||
return {
|
||||
ok: true,
|
||||
result: {
|
||||
grants: [
|
||||
{
|
||||
method: 'mobileWeb.files.watch',
|
||||
mode: 'subscription',
|
||||
workspaceParam: 'worktree',
|
||||
unsubscribeMethod: 'files.unwatch',
|
||||
maxRequestBytes: 1024,
|
||||
maxResponseBytes: 512 * 1024
|
||||
},
|
||||
{
|
||||
method: 'future.events',
|
||||
mode: 'subscription',
|
||||
workspaceParam: 'scope',
|
||||
unsubscribeMethod: 'future.release',
|
||||
maxRequestBytes: 1024,
|
||||
maxResponseBytes: 512 * 1024
|
||||
}
|
||||
}
|
||||
: { ok: false, error: { code: 'method_not_found', message: 'Old host' } }
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
const bridge = createMobileWebBridgeRoundtripFixture({
|
||||
grants: MOBILE_WEB_PRODUCTION_GRANTS.filter(
|
||||
(grant) => genericShell || grant.operation !== 'hostSubscribe'
|
||||
),
|
||||
grants: MOBILE_WEB_PRODUCTION_GRANTS,
|
||||
rpcClient: { sendRequest, subscribe } as unknown as RpcClient
|
||||
})
|
||||
return { ...bridge, subscribe, unsubscribe, emit: (event: unknown) => emit(event) }
|
||||
}
|
||||
|
||||
describe('generic subscription bridge compatibility', () => {
|
||||
it.each([[true, true]])('source-control catalog=%s shell=%s', async (catalog, shell) => {
|
||||
const f = fixture(catalog, shell)
|
||||
it('subscribes to source control through the generic shell lane', async () => {
|
||||
const f = fixture()
|
||||
const workspace = (await f.client.workspaceSnapshot({ limit: 10 })).workspaces[0]!.id
|
||||
const onEvent = vi.fn()
|
||||
const onError = vi.fn()
|
||||
@@ -68,11 +64,9 @@ describe('generic subscription bridge compatibility', () => {
|
||||
onError
|
||||
)
|
||||
await subscription.ready
|
||||
const generic = catalog && shell
|
||||
expect(f.subscribe.mock.calls[0]?.[0]).toBe(generic ? 'mobileWeb.files.watch' : 'files.watch')
|
||||
expect(f.subscribe.mock.calls[0]?.[0]).toBe('mobileWeb.files.watch')
|
||||
f.emit({
|
||||
type: 'changed',
|
||||
...(generic ? {} : { worktree: 'id:host-workspace' }),
|
||||
events: [],
|
||||
futureField: 'new'
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user