fix(client-ui-plugin-config): refresh the key badge when the Host reports the credential changed
The card read the credential only when its settings scope published, and a credential is not part of any settings section: a key written from the Models page — which addresses the same reference — left this badge reporting a state the Host had already replaced. It now re-reads on credentials/changed for the reference it watches, and ignores the event for any other reference.
This commit is contained in:
@@ -17,14 +17,15 @@ async function bench() {
|
||||
await ctx.plugin(SlotsService).await()
|
||||
const locale = new LocaleService(ctx)
|
||||
ctx.provide('locale', locale)
|
||||
const describeCredentials = vi.fn(() => Promise.resolve({ rpcId: 'c', result: { ok: false, error: {} } }))
|
||||
ctx.provide('connection', {
|
||||
isLoopback: true,
|
||||
api: {
|
||||
settings: { describe: vi.fn(() => Promise.resolve({ rpcId: 's', result: { ok: false, error: {} } })) },
|
||||
credentials: { describe: vi.fn(() => Promise.resolve({ rpcId: 'c', result: { ok: false, error: {} } })) },
|
||||
credentials: { describe: describeCredentials },
|
||||
},
|
||||
} as never)
|
||||
return { ctx, slots: ctx.get('slots') as SlotsService }
|
||||
return { ctx, slots: ctx.get('slots') as SlotsService, describeCredentials }
|
||||
}
|
||||
|
||||
function declareRoot(slots: SlotsService): () => void {
|
||||
@@ -76,6 +77,33 @@ describe('ui-plugin-config apply', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('re-reads the credential when the Host reports the watched reference changed', async () => {
|
||||
const { ctx, slots, describeCredentials } = await bench()
|
||||
declareRoot(slots)
|
||||
await ctx.plugin({ inject: [...inject], apply }).await()
|
||||
await vi.waitFor(() => { expect(describeCredentials).toHaveBeenCalled() })
|
||||
describeCredentials.mockClear()
|
||||
|
||||
// A key written on another surface changes no settings section, so this
|
||||
// event is the only thing that reaches the card.
|
||||
ctx.emit('credentials/changed', 'DEEPSEEK_API_KEY')
|
||||
|
||||
await vi.waitFor(() => { expect(describeCredentials).toHaveBeenCalledTimes(1) })
|
||||
})
|
||||
|
||||
it('ignores a credential change for a reference no card watches', async () => {
|
||||
const { ctx, slots, describeCredentials } = await bench()
|
||||
declareRoot(slots)
|
||||
await ctx.plugin({ inject: [...inject], apply }).await()
|
||||
await vi.waitFor(() => { expect(describeCredentials).toHaveBeenCalled() })
|
||||
describeCredentials.mockClear()
|
||||
|
||||
ctx.emit('credentials/changed', 'SOME_OTHER_KEY')
|
||||
await Promise.resolve()
|
||||
|
||||
expect(describeCredentials).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('registers into a declaration that arrives after apply', async () => {
|
||||
const { ctx, slots } = await bench()
|
||||
await ctx.plugin({ inject: [...inject], apply }).await()
|
||||
|
||||
@@ -436,6 +436,30 @@ describe('WebSearchCardController', () => {
|
||||
expect(credentials.set).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('re-reads when the Host reports the watched reference changed', async () => {
|
||||
const host = stubSettingsScope<WebSearchSettings>()
|
||||
const credentials = credentialsApi(false)
|
||||
const controller = new WebSearchCardController(host.scope, credentials.api)
|
||||
host.publish({ status: 'ready', writable: true, value: {}, user: {} })
|
||||
await vi.waitFor(() => { expect(credentials.describe).toHaveBeenCalled() })
|
||||
credentials.describe.mockClear()
|
||||
|
||||
// Another reference is not this card's business.
|
||||
controller.refreshCredential('OTHER_KEY')
|
||||
expect(credentials.describe).not.toHaveBeenCalled()
|
||||
|
||||
// A key written on another surface reaches this card only through this signal.
|
||||
credentials.describe.mockImplementation(() => Promise.resolve({
|
||||
rpcId: 'c-1' as never,
|
||||
result: { ok: true as const, value: { credentials: { DEEPSEEK_API_KEY: { configured: true, writable: true } } } },
|
||||
}))
|
||||
controller.refreshCredential('DEEPSEEK_API_KEY')
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(controller.inject().hooks.webSearchCard.getSnapshot().apiKeyConfigured).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
it('addresses the reference the section declares rather than the default', async () => {
|
||||
const host = stubSettingsScope<WebSearchSettings>()
|
||||
const credentials = credentialsApi(false)
|
||||
|
||||
Reference in New Issue
Block a user