Ver código fonte

test(api): align migrated client contracts

imccyu 1 mês atrás
pai
commit
89ee54ebb7

+ 4 - 4
packages/api/session-controller/tests/session-open-workspace-path.host.spec.ts

@@ -114,11 +114,11 @@ describe('session/openWorkspacePath', () => {
     }, aborted.signal)).rejects.toMatchObject({ failure: { code: 'cancelled' } })
 
     inspect.mockRejectedValueOnce('storage offline')
-    await expect(controller.openWorkspacePath({
+    const failed = controller.openWorkspacePath({
       sessionId: SessionId('inspection-failed'), path: 'result.html',
-    }, new AbortController().signal)).rejects.toMatchObject({
-      failure: { code: 'internal', message: expect.stringContaining('storage offline') },
-    })
+    }, new AbortController().signal)
+    await expect(failed).rejects.toMatchObject({ failure: { code: 'internal' } })
+    await expect(failed).rejects.toThrow('storage offline')
   })
 
   it('classifies opener cancellation and non-Error failures', async () => {

+ 9 - 12
packages/api/session-controller/tests/session-skills.host.spec.ts

@@ -183,10 +183,9 @@ describe('SessionSkillCatalog', () => {
     } as never)
     const catalog = new SessionSkillCatalog(ctx)
 
-    await expect(catalog.list({ sessionId }, new AbortController().signal))
-      .rejects.toMatchObject({
-        failure: { code: 'internal', message: expect.stringContaining('skill registry is absent') },
-      })
+    const failed = catalog.list({ sessionId }, new AbortController().signal)
+    await expect(failed).rejects.toMatchObject({ failure: { code: 'internal' } })
+    await expect(failed).rejects.toThrow('skill registry is absent')
   })
 
   it('rejects observations without projections or a project cwd', async () => {
@@ -199,14 +198,12 @@ describe('SessionSkillCatalog', () => {
     ctx.provide('sessionQuery', { observeSession } as never)
     const catalog = new SessionSkillCatalog(ctx)
 
-    await expect(catalog.list({ sessionId }, new AbortController().signal))
-      .rejects.toMatchObject({
-        failure: { code: 'internal', message: expect.stringContaining('projected Session observation') },
-      })
-    await expect(catalog.list({ sessionId }, new AbortController().signal))
-      .rejects.toMatchObject({
-        failure: { code: 'internal', message: expect.stringContaining('has no project cwd') },
-      })
+    const unprojected = catalog.list({ sessionId }, new AbortController().signal)
+    await expect(unprojected).rejects.toMatchObject({ failure: { code: 'internal' } })
+    await expect(unprojected).rejects.toThrow('projected Session observation')
+    const cwdless = catalog.list({ sessionId }, new AbortController().signal)
+    await expect(cwdless).rejects.toMatchObject({ failure: { code: 'internal' } })
+    await expect(cwdless).rejects.toThrow('has no project cwd')
   })
 
   it('classifies a provider listing failure', async () => {

+ 9 - 4
packages/api/settings-controller/src/index.ts

@@ -37,6 +37,11 @@ export type * from './types.ts'
 
 const settingsNamespaceRequestSchema = z.object({ ns: z.string().min(1) })
 
+/** Read abort state afresh after an awaited provider or opener call. */
+function isAborted(signal: AbortSignal): boolean {
+  return signal.aborted
+}
+
 /** Native document-opening policy. */
 export interface Config {
   /** Override platform desktop-opener detection. */
@@ -185,23 +190,23 @@ export class SettingsController extends TypertRemoteService {
   @Remote
   async openSettingsDocument(signal: AbortSignal): Promise<SettingsDocumentOpenValue> {
     const settings = this.provider()
-    if (signal.aborted) throw cancelled('settings document open was aborted')
+    if (isAborted(signal)) throw cancelled('settings document open was aborted')
     let path: string | undefined
     try {
       path = await settings.prepareDocument()
     } catch (error: unknown) {
-      if (signal.aborted) throw cancelled('settings document preparation was aborted')
+      if (isAborted(signal)) throw cancelled('settings document preparation was aborted')
       throw internal(`settings document preparation failed: ${messageOf(error)}`)
     }
     if (path === undefined) {
       throw internal('settings provider has no local document to open')
     }
-    if (signal.aborted) throw cancelled('settings document open was aborted')
+    if (isAborted(signal)) throw cancelled('settings document open was aborted')
     try {
       await this.openTextFile(path, signal)
       return { opened: true }
     } catch (error: unknown) {
-      if (signal.aborted) throw cancelled('settings document open was aborted')
+      if (isAborted(signal)) throw cancelled('settings document open was aborted')
       throw internal(`path open failed: ${messageOf(error)}`)
     }
   }

+ 7 - 5
packages/api/settings-controller/tests/settings-controller.host.spec.ts

@@ -263,13 +263,15 @@ describe('the settings Remote namespace a configuration page calls', () => {
 
   it('preserves settings-document absence, failure, and cancellation', async () => {
     const absent = await boot()
-    await expect(absent.controller.openSettingsDocument(new AbortController().signal))
-      .rejects.toMatchObject({ failure: { code: 'internal', message: expect.stringContaining('no local document') } })
+    const missingDocument = absent.controller.openSettingsDocument(new AbortController().signal)
+    await expect(missingDocument).rejects.toMatchObject({ failure: { code: 'internal' } })
+    await expect(missingDocument).rejects.toThrow('no local document')
 
     const failed = await boot(DocumentSettings)
     vi.spyOn(failed.ctx.settings, 'prepareDocument').mockRejectedValue(new Error('read failed'))
-    await expect(failed.controller.openSettingsDocument(new AbortController().signal))
-      .rejects.toMatchObject({ failure: { code: 'internal', message: expect.stringContaining('read failed') } })
+    const failedRead = failed.controller.openSettingsDocument(new AbortController().signal)
+    await expect(failedRead).rejects.toMatchObject({ failure: { code: 'internal' } })
+    await expect(failedRead).rejects.toThrow('read failed')
 
     const cancelled = new AbortController()
     cancelled.abort(new Error('cancelled'))
@@ -412,7 +414,7 @@ describe('the settings Remote namespace a configuration page calls', () => {
     ['unexpected preset failure', 'internal'],
   ] as const)('maps Agent preset resolution failure %#', async (error, code) => {
     const ctx = new Context()
-    ctx.provide('agentPresets', { resolve: () => Promise.reject(error) } as never)
+    ctx.provide('agentPresets', { resolve: async () => { throw error } } as never)
     const controller = new SettingsController(ctx)
 
     await expect(controller.openAgentPresetDirectory('mine', new AbortController().signal))

+ 2 - 4
packages/client/connection/src/client/fixture.ts

@@ -3657,12 +3657,10 @@ export class FixtureApiClient extends AbstractApiClient {
 
   /** Method-key dispatch into the in-memory contract impl (a real carrier routes by URL path instead). */
   private dispatch(
-    method: keyof RpcMethodMap,
+    _method: keyof RpcMethodMap,
     request: RpcRequest<never>,
   ): Promise<RpcResponse<unknown>> {
-    switch (method) {
-      case 'host.describe': return this.api.host.describe(request)
-    }
+    return this.api.host.describe(request)
   }
 
 }

+ 4 - 4
packages/client/ui-settings-plugins/tests/stores.client.spec.ts

@@ -668,7 +668,7 @@ describe('SubagentModelSelectionCardController', () => {
       })
       .mockImplementationOnce(() => refreshed.promise)
     const controller = new SubagentModelSelectionCardController(
-      host.scope, { modelCatalog: models } as never,
+      host.scope, { modelCatalog: models },
     )
     const face = controller.inject()
     const state = () => face.hooks.subagentModelSelectionCard.getSnapshot()
@@ -747,7 +747,7 @@ describe('SubagentModelSelectionCardController', () => {
         },
       })
     const controller = new SubagentModelSelectionCardController(
-      host.scope, { modelCatalog: models } as never,
+      host.scope, { modelCatalog: models },
     )
     const state = () => controller.inject().hooks.subagentModelSelectionCard.getSnapshot()
     await vi.waitFor(() => { expect(state().candidates[0]?.provider).toBe('alpha') })
@@ -802,7 +802,7 @@ describe('SubagentModelSelectionCardController', () => {
 
     const pending = deferred<never>()
     const models = vi.fn(() => pending.promise)
-    const controller = new SubagentModelSelectionCardController(host.scope, { modelCatalog: models } as never)
+    const controller = new SubagentModelSelectionCardController(host.scope, { modelCatalog: models })
     const face = controller.inject()
     face.toggleEnabled()
     face.retryCatalog()
@@ -814,7 +814,7 @@ describe('SubagentModelSelectionCardController', () => {
     const pendingResolve = deferred<never>()
     const resolving = new SubagentModelSelectionCardController(
       host.scope,
-      { modelCatalog: () => pendingResolve.promise } as never,
+      { modelCatalog: () => pendingResolve.promise },
     )
     const resolvingFace = resolving.inject()
     resolvingFace.toggleEnabled()