@@ -11,6 +11,8 @@ import { opencodeServerManager } from '../services/opencode-single-server'
1111import type { GitAuthService } from '../services/git-auth'
1212import type { OpenCodeSupervisor } from '../services/opencode-supervisor'
1313import { createStubOpenCodeClient } from '../../test/helpers/stub-opencode-client'
14+ import type { OpenCodeRestartCoordinator , ResumableSession } from '../services/opencode-restart-coordinator'
15+ import { setOpenCodeRestartCoordinator } from '../services/opencode-restart'
1416
1517interface TestUserPreferenceRow {
1618 preferences : string
@@ -450,3 +452,67 @@ describe('settings routes — opencode model discovery', () => {
450452 expect ( data . models ) . toEqual ( [ ] )
451453 } )
452454} )
455+
456+ describe ( 'settings routes — restart coordinator wiring' , ( ) => {
457+ let db : Database
458+ let app : Hono
459+
460+ beforeEach ( ( ) => {
461+ db = createTestDb ( )
462+ } )
463+
464+ afterEach ( ( ) => {
465+ db . close ( )
466+ setOpenCodeRestartCoordinator ( null )
467+ } )
468+
469+ it ( 'GET /opencode-active-sessions returns count and sessions from coordinator' , async ( ) => {
470+ const fakeCoordinator = {
471+ captureResumableSessions : vi . fn ( ( ) => [ {
472+ sessionID : 's1' ,
473+ directory : '/a' ,
474+ } satisfies ResumableSession ] ) ,
475+ abortSessions : vi . fn ( ) ,
476+ resumeSessions : vi . fn ( ) ,
477+ runWithResume : vi . fn ( ) ,
478+ } as unknown as OpenCodeRestartCoordinator
479+ setOpenCodeRestartCoordinator ( fakeCoordinator )
480+
481+ app = createTestApp ( db )
482+ const res = await app . request ( '/settings/opencode-active-sessions' )
483+ expect ( res . status ) . toBe ( 200 )
484+ const body = ( await res . json ( ) ) as { count : number ; sessions : ResumableSession [ ] }
485+ expect ( body . count ) . toBe ( 1 )
486+ expect ( body . sessions ) . toEqual ( [ { sessionID : 's1' , directory : '/a' } ] )
487+ expect ( fakeCoordinator . captureResumableSessions ) . toHaveBeenCalledTimes ( 1 )
488+ } )
489+
490+ it ( 'GET /opencode-active-sessions returns empty when no coordinator' , async ( ) => {
491+ setOpenCodeRestartCoordinator ( null )
492+ app = createTestApp ( db )
493+ const res = await app . request ( '/settings/opencode-active-sessions' )
494+ expect ( res . status ) . toBe ( 200 )
495+ const body = ( await res . json ( ) ) as { count : number ; sessions : ResumableSession [ ] }
496+ expect ( body . count ) . toBe ( 0 )
497+ expect ( body . sessions ) . toEqual ( [ ] )
498+ } )
499+
500+ it ( 'POST /opencode-restart routes through coordinator.runWithResume and returns resumedSessions' , async ( ) => {
501+ const runWithResume = vi . fn ( ) . mockResolvedValue ( { healthy : true , resumedSessionIDs : [ 's1' ] } )
502+ const fakeCoordinator = {
503+ captureResumableSessions : vi . fn ( ( ) => [ ] ) ,
504+ abortSessions : vi . fn ( ) ,
505+ resumeSessions : vi . fn ( ) ,
506+ runWithResume,
507+ } as unknown as OpenCodeRestartCoordinator
508+ setOpenCodeRestartCoordinator ( fakeCoordinator )
509+
510+ app = createTestApp ( db )
511+ const res = await app . request ( '/settings/opencode-restart' , { method : 'POST' } )
512+ expect ( res . status ) . toBe ( 200 )
513+ const body = ( await res . json ( ) ) as { success : boolean ; resumedSessions : string [ ] }
514+ expect ( body . success ) . toBe ( true )
515+ expect ( body . resumedSessions ) . toEqual ( [ 's1' ] )
516+ expect ( runWithResume ) . toHaveBeenCalledTimes ( 1 )
517+ } )
518+ } )
0 commit comments