fix(web): skip unavailable DeepSeek onboarding modal

This commit is contained in:
Yichen Jiang
2026-07-31 00:44:24 +08:00
parent c580b1b634
commit 15636fbb8e
12 changed files with 44 additions and 109 deletions
@@ -25,6 +25,7 @@ function fail<T>(message: string): RpcResponse<T> {
function harness(options: {
provider?: boolean
providerActive?: boolean
providerSettingsNs?: string
settingsNamespace?: boolean
apiKeyEnv?: string | null
literal?: boolean
@@ -32,16 +33,14 @@ function harness(options: {
credential?: { source?: string; writable: boolean }
describeFailure?: string
settingsWritable?: boolean
providersRejectOnce?: boolean
providersReject?: boolean
} = {}) {
let fileConfigured = false
let rejectProviders = options.providersRejectOnce === true
const configured = options.configured ?? (() => fileConfigured)
const face = {
llm: {
providers: () => {
if (rejectProviders) {
rejectProviders = false
if (options.providersReject === true) {
return Promise.reject(new Error('provider transport unavailable'))
}
return Promise.resolve(ok({
@@ -50,7 +49,7 @@ function harness(options: {
: [{
provider: 'deepseek-official',
displayName: 'DeepSeek',
settingsNs: 'llm-deepseek',
settingsNs: options.providerSettingsNs ?? 'llm-deepseek',
settingsPath: [],
active: options.providerActive ?? true,
}],
@@ -135,45 +134,20 @@ describe('DeepSeekOnboardingDialog', () => {
expect(h.openSection).not.toHaveBeenCalled()
})
it('routes an unavailable credential deployment to Models with a diagnostic', async () => {
const h = harness({ describeFailure: 'credentials service is absent' })
render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('dialog', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingCredentialsUnavailable)).toBeTruthy()
fireEvent.click(screen.getByRole('button', { name: en.onboardingGoToSettings }))
expect(h.openSection).toHaveBeenCalledWith('models')
})
it('explains read-only credential and settings deployments', async () => {
it('does not block the product when DeepSeek setup is unavailable', async () => {
for (const h of [
harness({ describeFailure: 'credentials service is absent' }),
harness({ credential: { writable: false } }),
harness({ settingsWritable: false }),
]) {
const view = render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('dialog', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingReadOnly)).toBeTruthy()
view.unmount()
}
})
it('distinguishes an initial transport failure from deployment misconfiguration', async () => {
const h = harness({ providersRejectOnce: true })
render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('dialog', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingLoadFailed)).toBeTruthy()
fireEvent.click(screen.getByRole('button', { name: en.onboardingGoToSettings }))
expect(h.openSection).toHaveBeenCalledWith('models')
})
it('uses the configuration diagnostic for inactive or unresolvable adapters', async () => {
for (const h of [
harness({ providersReject: true }),
harness({ providerActive: false }),
harness({ settingsNamespace: false }),
harness({ apiKeyEnv: null }),
]) {
const view = render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('dialog', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingConfigurationUnavailable)).toBeTruthy()
await act(async () => { await h.controller.load() })
expect(screen.queryByRole('dialog')).toBeNull()
expect(h.openSection).not.toHaveBeenCalled()
view.unmount()
}
})
@@ -181,6 +155,7 @@ describe('DeepSeekOnboardingDialog', () => {
it('skips an absent adapter and already-configured literal or environment credentials', async () => {
for (const h of [
harness({ provider: false }),
harness({ providerSettingsNs: '' }),
harness({ literal: true, describeFailure: 'credential seam absent' }),
harness({ configured: () => true, credential: { source: 'env', writable: false } }),
]) {
@@ -41,6 +41,14 @@ describe('deepSeekReadiness', () => {
expect(deepSeekReadiness(state({ status: 'idle', rows: [] }))).toEqual({ kind: 'loading' })
expect(deepSeekReadiness(state({ status: 'loading', rows: [] }))).toEqual({ kind: 'loading' })
expect(deepSeekReadiness(state({ rows: [] }))).toEqual({ kind: 'adapter-absent' })
expect(deepSeekReadiness(state({
rows: [row({
entry: {
...row().entry,
settingsNs: '',
},
})],
}))).toEqual({ kind: 'adapter-absent' })
})
it('reports a missing writable effective credential', () => {