Files
orca/src/main/browser/browser-client-upload-transfer.test.ts
T
Neil 7fb3b90efe test: retire browser and cookie-import cases their siblings already own (#23957)
Semantic sweep of src/main/browser, ssh, codex and native-chat. 28 cases removed
across 20 files, plus one file and the dead production wrapper behind it.

The find that keeps repeating is a test whose mocks leave nothing of production
between them and the assertion:
- `recordBrowserClientPagePublishedUrl` ignores `revision` entirely, so
  "overwrites the recorded url when a newer navigation arrives" varied a parameter
  the code never reads;
- `publish` calls `this.observeCurrentUrl?.(params)` unconditionally as its first
  statement, so "observes params the schema will reject rather than pre-filtering"
  asserted an unbranched line;
- with the executor mocked away, "does not observe publishes aimed at another
  environment" left only a `Map.get`;
- `mountPage`/`rekeyPage`/`retirePage` all delegate to one private `request()` that
  owns the timer, making "times out exactly once" a provider-local replay whose
  name promised a "once" it never asserted.

Two negative controls were passing for the wrong reason. "Rejects oversized browser
clipboard writes" fed a 16 MiB fixture, but `clipboardWrite` has one guard at 8 KiB,
so the refusal came from that guard rather than the clipboard limit its name claims
— the 8 KiB sibling stays. And "tolerates cancelling when nothing is armed" cannot
fail at all: `cancel()` is `if (this.timer)`-guarded and `clearTimeout(null)` is
legal, so removing the guard still passes.

`browser-cookie-import-app-bound-prefix.test.ts` is deleted as a private-predicate
test over dead code: `browser-cookie-import.ts:56` was a bare forwarding wrapper
around `browser-cookie-decryption`'s predicate, and `browser-cookie-chromium-scan.ts:51`
inlines `version === 'v20'` rather than calling either. The v20-row contract is
owned by `browser-cookie-import-undecryptable.test.ts`. The wrapper and its import
are removed with it, since that test was its only caller.
2026-09-29 17:54:12 -07:00

105 lines
3.6 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import type { BrowserClientHostCommandEvent } from '../../shared/browser-client-host-protocol'
import {
BROWSER_CLIENT_FILE_CHANNEL_READ_METHOD,
fetchBrowserClientUploadFiles,
readBrowserClientUploadPaths
} from './browser-client-upload-transfer'
const event = {
authorityRuntimeId: 'runtime-1',
authorityEpoch: 'epoch-1',
browserHostClientId: 'host-1',
browserHostGeneration: 2,
browserPageId: 'page-1',
pageHostGeneration: 3
} as BrowserClientHostCommandEvent
describe('fetchBrowserClientUploadFiles', () => {
it('reassembles a multi-chunk remote file and stamps the page authority on every read', async () => {
const requests: { method: string; params: Record<string, unknown> }[] = []
const chunks = ['abc', 'de']
const files = await fetchBrowserClientUploadFiles({
request: async (method, params) => {
requests.push({ method, params: params as Record<string, unknown> })
const chunk = chunks.shift() ?? ''
return {
contentBase64: Buffer.from(chunk).toString('base64'),
bytesRead: chunk.length,
totalBytes: 5,
eof: chunks.length === 0
}
},
event,
remotePaths: ['docs/a.txt']
})
expect(files).toEqual([{ remotePath: 'docs/a.txt', contents: Buffer.from('abcde') }])
expect(requests).toHaveLength(2)
expect(requests[0].method).toBe(BROWSER_CLIENT_FILE_CHANNEL_READ_METHOD)
expect(requests[0].params).toMatchObject({
fileChannelProtocolVersion: 1,
browserPageId: 'page-1',
pageHostGeneration: 3,
workspaceRelativePath: 'docs/a.txt',
offset: 0
})
expect(requests[1].params).toMatchObject({ offset: 3 })
})
it('stops instead of looping forever on a host that never reports eof', async () => {
await expect(
fetchBrowserClientUploadFiles({
request: async () => ({ contentBase64: '', bytesRead: 0, totalBytes: 0, eof: false }),
event,
remotePaths: ['a.txt']
})
).rejects.toThrow('browser_client_upload_transfer_stalled')
})
it('rejects a chunk whose declared length does not match its bytes', async () => {
await expect(
fetchBrowserClientUploadFiles({
request: async () => ({
contentBase64: Buffer.from('abc').toString('base64'),
bytesRead: 99,
totalBytes: 99,
eof: true
}),
event,
remotePaths: ['a.txt']
})
).rejects.toThrow('browser_client_upload_chunk_invalid')
})
it('rejects a request naming more files than the command budget allows', async () => {
await expect(
fetchBrowserClientUploadFiles({
request: async () => ({ contentBase64: '', bytesRead: 0, totalBytes: 0, eof: true }),
event,
remotePaths: Array.from({ length: 17 }, (_unused, index) => `${index}.txt`)
})
).rejects.toThrow('browser_client_upload_file_count_exceeded')
})
})
describe('readBrowserClientUploadPaths', () => {
it('accepts a list of non-empty path strings', () => {
expect(readBrowserClientUploadPaths({ files: ['a.txt', 'b/c.txt'] })).toEqual([
'a.txt',
'b/c.txt'
])
})
it('rejects a missing, non-array, or non-string files payload', () => {
expect(() => readBrowserClientUploadPaths({})).toThrow('browser_client_upload_files_required')
expect(() => readBrowserClientUploadPaths({ files: 'a.txt' })).toThrow(
'browser_client_upload_files_required'
)
expect(() => readBrowserClientUploadPaths({ files: [''] })).toThrow(
'browser_client_upload_files_required'
)
})
})