test(desktop): cover scoped onboarding runtime readiness checks

Assert setup.runtime_check honors provider params and that Nous OAuth
onboarding persists model config before validating the connected provider.
This commit is contained in:
infinitycrew39 2026-06-24 23:19:51 +07:00
parent 6da615c77c
commit d8fe1c0b41
3 changed files with 93 additions and 2 deletions

View file

@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest'
import { interpretRuntimeReadiness } from './runtime-readiness'
import { evaluateRuntimeReadiness, fetchRuntimeReadinessSignals, interpretRuntimeReadiness } from './runtime-readiness'
describe('interpretRuntimeReadiness', () => {
it('prefers runtime_check when both signals exist', () => {
@ -63,3 +63,51 @@ describe('interpretRuntimeReadiness', () => {
expect(result.reason).toBe('setup.runtime_check timeout')
})
})
describe('fetchRuntimeReadinessSignals', () => {
it('scopes setup.runtime_check to the requested provider', async () => {
const calls: Array<{ method: string; params?: Record<string, unknown> }> = []
const requestGateway = async <T = unknown>(method: string, params?: Record<string, unknown>) => {
calls.push({ method, params })
if (method === 'setup.status') {
return { provider_configured: true } as T
}
if (method === 'setup.runtime_check') {
return { ok: true } as T
}
throw new Error(`unexpected method: ${method}`)
}
await fetchRuntimeReadinessSignals(requestGateway, 'nous')
expect(calls).toEqual([
{ method: 'setup.status' },
{ method: 'setup.runtime_check', params: { provider: 'nous' } }
])
})
})
describe('evaluateRuntimeReadiness', () => {
it('forwards requestedProvider to setup.runtime_check', async () => {
const requestGateway = async <T = unknown>(method: string, params?: Record<string, unknown>) => {
if (method === 'setup.status') {
return { provider_configured: true } as T
}
if (method === 'setup.runtime_check') {
expect(params).toEqual({ provider: 'nous' })
return { ok: true } as T
}
throw new Error(`unexpected method: ${method}`)
}
const result = await evaluateRuntimeReadiness(requestGateway, { requestedProvider: 'nous' })
expect(result.ready).toBe(true)
})
})

View file

@ -194,7 +194,7 @@ describe('OAuth onboarding', () => {
throw new Error(`unexpected api path: ${path}`)
})
const requestGateway: OnboardingContext['requestGateway'] = async method => {
const requestGateway: OnboardingContext['requestGateway'] = async (method, params) => {
if (method === 'reload.env') {
return {} as never
}
@ -204,6 +204,8 @@ describe('OAuth onboarding', () => {
}
if (method === 'setup.runtime_check') {
expect(params).toEqual({ provider: 'nous' })
return { ok: true } as never
}
@ -241,6 +243,14 @@ describe('OAuth onboarding', () => {
}
expect(calls.some(c => c.path === '/api/model/set')).toBe(true)
const optionsIndex = calls.findIndex(c => c.path === '/api/model/options')
const recommendedIndex = calls.findIndex(c => c.path.startsWith('/api/model/recommended-default'))
const setIndex = calls.findIndex(c => c.path === '/api/model/set')
expect(optionsIndex).toBeGreaterThanOrEqual(0)
expect(recommendedIndex).toBeGreaterThan(optionsIndex)
expect(setIndex).toBeGreaterThan(recommendedIndex)
})
})

View file

@ -2784,6 +2784,39 @@ def test_setup_runtime_check_rejects_implicit_bedrock_when_unconfigured(monkeypa
assert resp["result"]["provider"] == "bedrock"
def test_setup_runtime_check_honors_requested_provider(monkeypatch):
"""Onboarding must be able to validate the provider the user just connected."""
monkeypatch.setattr("hermes_cli.main._has_any_provider_configured", lambda: True)
def fake_resolve(requested=None, **kwargs):
if requested == "nous":
return {
"provider": "nous",
"api_key": "invoke-jwt",
"source": "portal",
}
return {
"provider": "anthropic",
"api_key": "",
"source": "config",
}
monkeypatch.setattr(
"hermes_cli.runtime_provider.resolve_runtime_provider",
fake_resolve,
)
scoped = server.handle_request(
{"id": "1", "method": "setup.runtime_check", "params": {"provider": "nous"}}
)
assert scoped["result"]["ok"] is True
assert scoped["result"]["provider"] == "nous"
default = server.handle_request({"id": "1", "method": "setup.runtime_check", "params": {}})
assert default["result"]["ok"] is False
assert default["result"]["provider"] == "anthropic"
def test_complete_slash_drops_removed_provider_alias():
# `/provider` was folded into a single `/model` command, so autocomplete
# must no longer offer the dead alias...