Files
orca/mobile/src/components/ProtocolBlockScreen.test.ts
T
OrcaWinandOrcaWin d714d577bf test: remove 45 low-value suites and redundant cases (#40072)
* test: remove low-value synthetic and duplicated cases

* test: remove low-value IPC and renderer cases

* test: remove marginal mobile web build helper cases

* test: remove marginal browser coverage

* test: remove low-value mobile coverage

* test: remove fixture inventories and diagnostic-only cases

* test: remove low-value shared test suites and matrices

* test: remove internal-work and mock-only coverage

* test: remove prose passthrough and scan-count assertions

* test: remove low-value renderer suites and copy counters

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 19:50:37 -08:00

177 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { createElement } from 'react'
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type { KnownAppUpdate } from '../storage/app-update-preferences'
import type { BlockedVerdict } from './ProtocolBlockScreen'
import { ProtocolBlockScreen } from './ProtocolBlockScreen'
const nativeTestState = vi.hoisted(() => {
// Declared wide so a test can switch stores; an assertion here would only widen the same literal.
const platform: { OS: 'ios' | 'android' } = { OS: 'ios' }
return { openUrl: vi.fn(), platform }
})
const wallUpdate = vi.hoisted(() => {
const state: { current: KnownAppUpdate | null } = { current: null }
return state
})
// The release the installed app's update check found; the real hook imports the checker module.
vi.mock('../app-update/use-wall-app-update', () => ({ useWallAppUpdate: () => wallUpdate.current }))
vi.mock('react-native', () => ({
Linking: { openURL: nativeTestState.openUrl },
Platform: nativeTestState.platform,
Pressable: 'Pressable',
StyleSheet: { create: <T>(styles: T) => styles },
Text: 'Text',
View: 'View'
}))
vi.mock('expo-router', () => ({
router: { replace: vi.fn() },
// Mock native handoff’s router hook; web sibling posts target to shell.
useRouter: () => ({ replace: vi.fn(), push: vi.fn(), back: vi.fn(), dismissTo: vi.fn() })
}))
const RELEASES_URL = 'https://github.com/stablyai/orca/releases'
let renderer: ReactTestRenderer | null = null
function render(verdict: BlockedVerdict, mobileUpdate: KnownAppUpdate | null = null): string {
wallUpdate.current = mobileUpdate
act(() => {
renderer = create(createElement(ProtocolBlockScreen, { verdict }))
})
return JSON.stringify(renderer?.toJSON())
}
/** The mocked host components are plain strings, which `ElementType` does not admit. */
function isMockedHostElement(type: unknown, name: string): boolean {
return type === name
}
function pressableCount(): number {
return renderer?.root.findAll((node) => isMockedHostElement(node.type, 'Pressable')).length ?? 0
}
function primaryActionUrl(): unknown {
const pressable = renderer?.root.findAll((node) => isMockedHostElement(node.type, 'Pressable'))[0]
act(() => pressable?.props.onPress())
return nativeTestState.openUrl.mock.calls[0]?.[0]
}
describe('ProtocolBlockScreen', () => {
beforeEach(() => {
nativeTestState.openUrl.mockClear()
nativeTestState.platform.OS = 'ios'
})
afterEach(() => {
act(() => renderer?.unmount())
renderer = null
})
it('tells a host without a bundle, or without this screen, the desktop is too old', () => {
for (const reason of ['bundle-unavailable', 'page-route-unlisted'] as const) {
const output = render({ kind: 'blocked', reason })
expect(output).toContain('Update Orca on your computer')
expect(output).toContain(
'This paired desktop app is too old for your current Orca Mobile app. Update Orca on your computer, then try this host again.'
)
expect(output).not.toContain('does not include the mobile workspace')
expect(primaryActionUrl()).toBe(RELEASES_URL)
}
})
it('sends an unknown manifest schema to the mobile update', () => {
const output = render({
kind: 'blocked',
reason: 'bundle-shell-too-old',
schemaVersion: 2
})
expect(output).toContain('Update Orca Mobile')
expect(output).toContain(
"This desktop's mobile workspace needs a newer Orca Mobile app. Update Orca Mobile from the App Store, then try this host again."
)
expect(primaryActionUrl()).toBe('itms-apps://apps.apple.com/app/orca-ide/id6766130217')
})
it('offers no download for a cached bundle the host outgrew, because none would clear it', () => {
const output = render({
kind: 'blocked',
reason: 'bundle-incompatible',
side: 'mobile',
bundleRuntimeProtocolVersion: 3,
requiredBundleRuntimeProtocolVersion: 4
})
expect(output).toContain('Refresh the mobile workspace')
expect(output).toContain(
'The workspace cached for this host is older than the desktop expects. Reconnect to this host to download the current one.'
)
// A store update cannot replace a stale cache, so neither store link is offered.
expect(output).not.toContain('Open App Store')
expect(output).not.toContain('Open GitHub Releases')
expect(output).not.toContain('Update Orca')
// Back to hosts is the only button left, and it is not a download.
expect(pressableCount()).toBe(1)
expect(output).toContain('Back to hosts')
// Nothing was "already updated" here; the note keeps only the pairing fallback.
expect(output).not.toContain('Already updated?')
expect(output).toContain('If this message stays, remove this host and pair it again.')
})
it('sends a host older than its own bundle to the desktop update', () => {
const output = render({
kind: 'blocked',
reason: 'bundle-incompatible',
side: 'desktop',
hostProtocolVersion: 1,
requiredHostProtocolVersion: 2
})
expect(output).toContain('Update Orca on your computer')
expect(output).toContain('This paired desktop app is too old for your current Orca Mobile app')
expect(primaryActionUrl()).toBe(RELEASES_URL)
})
describe('with the newest release known', () => {
const release = {
version: '0.0.52',
url: 'https://github.com/stablyai/orca/releases/tag/mobile-v0.0.52'
}
it.each(['android'] as const)('opens that exact release on %s', (os) => {
nativeTestState.platform.OS = os
const output = render(
{ kind: 'blocked', reason: 'bundle-shell-too-old', schemaVersion: 2 },
release
)
expect(output).toContain('Get Orca 0.0.52')
expect(output).not.toContain('Open App Store')
expect(output).not.toContain('Open GitHub Releases')
expect(primaryActionUrl()).toBe(release.url)
})
it('leaves the desktop wall on the desktop releases', () => {
const output = render({ kind: 'blocked', reason: 'bundle-unavailable' }, release)
expect(output).not.toContain('Get Orca')
expect(primaryActionUrl()).toBe(RELEASES_URL)
})
})
it.each([
['ios', 'Open App Store', 'itms-apps://apps.apple.com/app/orca-ide/id6766130217'],
['android', 'Open GitHub Releases', RELEASES_URL]
] as const)('keeps the %s store link when no release is known', (os, label, url) => {
nativeTestState.platform.OS = os
const output = render(
{ kind: 'blocked', reason: 'mobile-too-old', desktopVersion: 5, requiredMobileVersion: 9 },
null
)
expect(output).toContain(label)
expect(output).not.toContain('Get Orca')
expect(primaryActionUrl()).toBe(url)
})
})