mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 00:02:10 +00:00
test(browser): guard the identity capability and harden two weak assertions
Pins the mixed-version guarantee that had no test: browser.identity.v1 is advertised when the identity store is initialized and absent when it is not. Verified discriminating -- advertising it unconditionally fails the test. The profileCreate rejection test asserted ok:false against a runtime with no browserProfileCreate, so that assertion passed even when the retired field was accepted. It now stubs a working runtime method, making ok:false load-bearing, and asserts the runtime is never reached. Removes the persistence fixture's dead failIdentityWrite branch on writeFileAtomically: nothing on that path calls it, so it implied a second write mechanism that does not exist. Failure is injected through node:fs, which is what the identity write actually uses.
This commit is contained in:
@@ -164,10 +164,9 @@ function installModuleMocks(
|
||||
fsState.files.set(targetKey, value)
|
||||
}
|
||||
}),
|
||||
// Nothing on this path calls writeFileAtomically; it is here only to keep the module shape
|
||||
// complete. The identity write goes through node:fs above, which is where failure is injected.
|
||||
writeFileAtomically: vi.fn((pathValue: string, data: string) => {
|
||||
if (failIdentityWrite && pathValue.endsWith('browser-identity-mode.json')) {
|
||||
throw new Error('read-only userData')
|
||||
}
|
||||
const key = fsKey(pathValue)
|
||||
fsState.files.set(key, data)
|
||||
fsState.present.add(key)
|
||||
|
||||
@@ -23,8 +23,29 @@ import {
|
||||
attachClientBrowserHost,
|
||||
publishClientHostedPage
|
||||
} from '../orca-runtime-test-scenario-builders.spec'
|
||||
import { mkdtempSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import {
|
||||
initializeBrowserIdentityModeStore,
|
||||
resetBrowserIdentityModeStoreForTests
|
||||
} from '../../browser/browser-identity-mode-store'
|
||||
|
||||
describe('OrcaRuntimeService', () => {
|
||||
// The mixed-version guarantee: a host that never initialized the identity store must not
|
||||
// advertise a method that can only throw there.
|
||||
it('advertises the browser identity capability only where an identity store exists', () => {
|
||||
resetBrowserIdentityModeStoreForTests()
|
||||
expect(createRuntime().getStatus().capabilities).not.toContain('browser.identity.v1')
|
||||
|
||||
initializeBrowserIdentityModeStore(mkdtempSync(join(tmpdir(), 'orca-identity-capability-')))
|
||||
try {
|
||||
expect(createRuntime().getStatus().capabilities).toContain('browser.identity.v1')
|
||||
} finally {
|
||||
resetBrowserIdentityModeStoreForTests()
|
||||
}
|
||||
})
|
||||
|
||||
it('advertises headless browser capability when an offscreen backend backs a windowless host', () => {
|
||||
const runtime = createRuntime()
|
||||
runtime.setOffscreenBrowserBackend({ createTab: vi.fn(), closeTab: vi.fn() })
|
||||
|
||||
@@ -77,8 +77,12 @@ describe('browser RPC methods', () => {
|
||||
// The schema check above proves the shape; this proves an older client actually gets the
|
||||
// rejection over the wire instead of a success with the field quietly dropped.
|
||||
it('rejects the retired profile user-agent field through the dispatcher', async () => {
|
||||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: params parsing fails before any runtime member is read.
|
||||
const runtime = { getRuntimeId: () => 'test-runtime' } as unknown as OrcaRuntimeService
|
||||
const browserProfileCreate = vi.fn().mockResolvedValue({ id: 'profile-1' })
|
||||
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the dispatcher reads only getRuntimeId and the single browser method stubbed here.
|
||||
const runtime = {
|
||||
getRuntimeId: () => 'test-runtime',
|
||||
browserProfileCreate
|
||||
} as unknown as OrcaRuntimeService
|
||||
const dispatcher = new RpcDispatcher({ runtime, methods: BROWSER_CORE_METHODS })
|
||||
|
||||
const response = await dispatcher.dispatch(
|
||||
@@ -89,8 +93,11 @@ describe('browser RPC methods', () => {
|
||||
})
|
||||
)
|
||||
|
||||
// Why a working runtime stub: if the field were accepted and stripped again the call would
|
||||
// succeed, so every assertion below is load-bearing rather than passing on a missing method.
|
||||
expect(response).toMatchObject({ ok: false })
|
||||
expect(JSON.stringify(response)).toContain('browser_profile_user_agent_mode_is_now_app_wide')
|
||||
expect(browserProfileCreate).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('routes core browser automation commands to the runtime server', async () => {
|
||||
|
||||
Reference in New Issue
Block a user