test(mobile): pin the ui.get trust blank, and correct two stale acceptance comments

The goldens cannot catch a regression to `if (uiResult?.result)`: the scenario's
success reply is `{"ui":{}}`, so every partition of
matrix-settings.workspace-context-ui.get-1 records the same `trust:{}` state. The
new case answers once with real trust and again with a null result on a fresh
client, which is the only shape where skipping the blank is observable —
trustedOrcaHooks gates the setup-hook approval prompt in
use-new-workspace-create-submit.ts, so a stale value would skip it.

settingsRead's comment still claimed workspace context, which this branch moved to
optionalSettingsRead; both comments now name their real callers.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
This commit is contained in:
Jinwoo-H
2026-09-14 02:27:32 -04:00
parent 4c1709adf4
commit 5ec0b2698f
2 changed files with 30 additions and 15 deletions
@@ -40,25 +40,31 @@ function clientAnswering(settingsResult: unknown, uiResult: unknown): RpcClient
describe('useNewWorkspaceRuntimeContext', () => {
let renderer: ReactTestRenderer | null = null
let context: RuntimeContext | null = null
afterEach(() => {
act(() => renderer?.unmount())
renderer = null
context = null
})
async function mount(settingsResult: unknown, uiResult: unknown): Promise<PublishedState> {
// One client for the whole mount: the hook keys its effect on client identity.
const client = clientAnswering(settingsResult, uiResult)
let context!: RuntimeContext
function Harness(): null {
context = useNewWorkspaceRuntimeContext(client, true)
return null
}
function Harness({ client }: { client: RpcClient }): null {
context = useNewWorkspaceRuntimeContext(client, true)
return null
}
/** Answering twice re-renders the live harness, so the second call is a host swap, not a remount. */
async function answer(settingsResult: unknown, uiResult: unknown): Promise<PublishedState> {
const element = createElement(Harness, { client: clientAnswering(settingsResult, uiResult) })
await act(async () => {
renderer = create(createElement(Harness))
if (renderer) {
renderer.update(element)
} else {
renderer = create(element)
}
})
await act(async () => {})
const { runtimeSettings, trustedOrcaHooks, availableProviders } = context
const { runtimeSettings, trustedOrcaHooks, availableProviders } = context!
return { runtimeSettings, trustedOrcaHooks, availableProviders }
}
@@ -69,7 +75,7 @@ describe('useNewWorkspaceRuntimeContext', () => {
['absent', undefined],
['without a settings member', {}]
])('degrades a %s settings result to absent settings', async (_label, settingsResult) => {
expect(await mount(settingsResult, UI_WITH_TRUST)).toEqual({
expect(await answer(settingsResult, UI_WITH_TRUST)).toEqual({
runtimeSettings: null,
trustedOrcaHooks: TRUSTED_HOOKS,
availableProviders: ['github']
@@ -83,15 +89,24 @@ describe('useNewWorkspaceRuntimeContext', () => {
['absent', undefined],
['without a ui member', {}]
])('degrades a %s ui result to untrusted hooks', async (_label, uiResult) => {
expect(await mount({ settings: SETTINGS }, uiResult)).toEqual({
expect(await answer({ settings: SETTINGS }, uiResult)).toEqual({
runtimeSettings: SETTINGS,
trustedOrcaHooks: {},
availableProviders: ['github']
})
})
// The blank, not just the absence of a throw: trustedOrcaHooks gates the setup-hook approval
// prompt in use-new-workspace-create-submit.ts, so a stale value would skip it.
it('blanks the trust an earlier host published when the next ui result is null', async () => {
expect((await answer({ settings: SETTINGS }, UI_WITH_TRUST)).trustedOrcaHooks).toEqual(
TRUSTED_HOOKS
)
expect((await answer({ settings: SETTINGS }, null)).trustedOrcaHooks).toEqual({})
})
it('publishes the settings and trust a host does send', async () => {
expect(await mount({ settings: SETTINGS }, UI_WITH_TRUST)).toEqual({
expect(await answer({ settings: SETTINGS }, UI_WITH_TRUST)).toEqual({
runtimeSettings: SETTINGS,
trustedOrcaHooks: TRUSTED_HOOKS,
availableProviders: ['github']
@@ -38,7 +38,7 @@ const botOverridesReader: RpcCompatibleReader<unknown, 'bot-logins', string[]> =
}
}
/** Workspace context, submit, task hydration/create and home providers share this acceptance. */
/** Submit, task hydration/create and home providers: a null result throws the settings read. */
export const settingsRead = bindDeferredRpcOperation(
defineRpcOperation({
name: 'settings.member-or-skip',
@@ -49,7 +49,7 @@ export const settingsRead = bindDeferredRpcOperation(
})
)
/** A null or absent result reads as absent settings instead of throwing the property read. */
/** Workspace context, history resume and repo metadata: a null result reads as absent settings. */
export const optionalSettingsRead = bindDeferredRpcOperation(
defineRpcOperation({
name: 'settings.optional-member-or-skip',