Files
orca/mobile/src/source-control/reveal-mobile-source-control-session-diff.test.ts
T
Brennan Benson 7f4570c9a6 fix(mobile): activate Source Control diff tabs on phones (#12770)
* fix(mobile): activate source-control diff tabs on phones

* fix(mobile): reveal legacy source control file tabs
2026-08-05 13:36:08 -07:00

234 lines
6.7 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from 'vitest'
import type { RpcClient } from '../transport/rpc-client'
import type { RpcResponse } from '../transport/types'
import { revealMobileSourceControlSessionDiff } from './reveal-mobile-source-control-session-diff'
function success(result: unknown): RpcResponse {
return { id: 'rpc-1', ok: true, result, _meta: { runtimeId: 'runtime-1' } }
}
function clientWith(sendRequest: RpcClient['sendRequest']): Pick<RpcClient, 'sendRequest'> {
return { sendRequest }
}
function options(sendRequest: RpcClient['sendRequest']) {
return {
client: clientWith(sendRequest),
worktreeId: 'worktree-1',
relativePath: 'src/target.ts',
tabMode: 'diff' as const,
staged: true
}
}
afterEach(() => {
vi.useRealTimers()
})
describe('revealMobileSourceControlSessionDiff', () => {
it('activates the requested file when its diff tab is already open', async () => {
const sendRequest = vi
.fn<RpcClient['sendRequest']>()
.mockResolvedValueOnce(
success({
activeTabId: 'agent-tab',
tabs: [
{ id: 'agent-tab', type: 'terminal' },
{
id: 'other-diff',
type: 'file',
mode: 'diff',
diffSource: 'staged',
relativePath: 'src/other.ts'
},
{
id: 'target-diff',
type: 'file',
mode: 'diff',
diffSource: 'staged',
relativePath: 'src/target.ts'
}
]
})
)
.mockResolvedValueOnce(success({ activeTabId: 'target-diff' }))
await expect(revealMobileSourceControlSessionDiff(options(sendRequest))).resolves.toBe(
'revealed'
)
expect(sendRequest).toHaveBeenNthCalledWith(2, 'session.tabs.activate', {
worktree: 'id:worktree-1',
tabId: 'target-diff',
notifyClients: false,
navigation: 'caller',
intent: 'user'
})
})
it('selects the staged diff when both versions of a file are open', async () => {
const sendRequest = vi
.fn<RpcClient['sendRequest']>()
.mockResolvedValueOnce(
success({
tabs: [
{
id: 'unstaged-diff',
type: 'file',
mode: 'diff',
diffSource: 'unstaged',
relativePath: 'src/target.ts'
},
{
id: 'staged-diff',
type: 'file',
mode: 'diff',
diffSource: 'staged',
relativePath: 'src/target.ts'
}
]
})
)
.mockResolvedValueOnce(success({ activeTabId: 'staged-diff' }))
await expect(revealMobileSourceControlSessionDiff(options(sendRequest))).resolves.toBe(
'revealed'
)
expect(sendRequest).toHaveBeenLastCalledWith(
'session.tabs.activate',
expect.objectContaining({ tabId: 'staged-diff' })
)
})
it('waits for the requested diff source instead of activating the other one', async () => {
vi.useFakeTimers()
const sendRequest = vi
.fn<RpcClient['sendRequest']>()
.mockResolvedValueOnce(
success({
tabs: [
{
id: 'unstaged-diff',
type: 'file',
mode: 'diff',
diffSource: 'unstaged',
relativePath: 'src/target.ts'
}
]
})
)
.mockResolvedValueOnce(
success({
tabs: [
{
id: 'staged-diff',
type: 'file',
mode: 'diff',
diffSource: 'staged',
relativePath: 'src/target.ts'
}
]
})
)
.mockResolvedValueOnce(success({ activeTabId: 'staged-diff' }))
const reveal = revealMobileSourceControlSessionDiff(options(sendRequest))
await vi.advanceTimersByTimeAsync(300)
await expect(reveal).resolves.toBe('revealed')
expect(sendRequest).toHaveBeenLastCalledWith(
'session.tabs.activate',
expect.objectContaining({ tabId: 'staged-diff' })
)
})
it('activates a legacy edit tab when opening a diff falls back to files.open', async () => {
const sendRequest = vi
.fn<RpcClient['sendRequest']>()
.mockResolvedValueOnce(
success({
tabs: [
{
id: 'stale-diff',
type: 'file',
mode: 'diff',
diffSource: 'staged',
relativePath: 'src/target.ts'
},
{
id: 'target-edit',
type: 'file',
relativePath: 'src/target.ts'
}
]
})
)
.mockResolvedValueOnce(success({ activeTabId: 'target-edit' }))
await expect(
revealMobileSourceControlSessionDiff({ ...options(sendRequest), tabMode: 'edit' })
).resolves.toBe('revealed')
expect(sendRequest).toHaveBeenLastCalledWith(
'session.tabs.activate',
expect.objectContaining({ tabId: 'target-edit' })
)
})
it('retries until the opened diff appears in the session snapshot', async () => {
vi.useFakeTimers()
const sendRequest = vi
.fn<RpcClient['sendRequest']>()
.mockResolvedValueOnce(success({ tabs: [{ id: 'agent-tab', type: 'terminal' }] }))
.mockResolvedValueOnce(
success({
tabs: [
{
id: 'target-diff',
type: 'file',
mode: 'diff',
diffSource: 'staged',
relativePath: 'src/target.ts'
}
]
})
)
.mockResolvedValueOnce(success({ activeTabId: 'target-diff' }))
const reveal = revealMobileSourceControlSessionDiff(options(sendRequest))
await vi.advanceTimersByTimeAsync(300)
await expect(reveal).resolves.toBe('revealed')
expect(sendRequest).toHaveBeenCalledTimes(3)
})
it('delegates to the mounted session when the dock callback is available', async () => {
const sendRequest = vi.fn<RpcClient['sendRequest']>()
const onOpenedFileDiff = vi.fn()
await expect(
revealMobileSourceControlSessionDiff({
...options(sendRequest),
onOpenedFileDiff
})
).resolves.toBe('revealed')
expect(onOpenedFileDiff).toHaveBeenCalledWith('src/target.ts')
expect(sendRequest).not.toHaveBeenCalled()
})
it('cancels route-owned polling after the source-control screen unmounts', async () => {
let current = true
const sendRequest = vi.fn<RpcClient['sendRequest']>().mockImplementation(async () => {
current = false
return success({ tabs: [] })
})
await expect(
revealMobileSourceControlSessionDiff({
...options(sendRequest),
isCurrent: () => current
})
).resolves.toBe('cancelled')
expect(sendRequest).toHaveBeenCalledOnce()
})
})