import { describe, expect, it, vi } from 'vitest' import { resolveGatewayRestartTargets, restartGatewaysForProfiles, } from '../../packages/server/src/services/hermes/gateway-autostart' describe('batch gateway restart', () => { it('maps each profile to its own gateway target in per-profile mode', () => { expect(resolveGatewayRestartTargets(['default', 'work'], false)).toEqual([ { targetProfile: 'default', requestedProfile: 'default' }, { targetProfile: 'work', requestedProfile: 'work' }, ]) }) it('restarts a shared gateway once in unified mode', () => { expect(resolveGatewayRestartTargets(['default', 'work', 'reviewer'], true)).toEqual([ { targetProfile: 'default', requestedProfile: 'default' }, ]) }) it('keeps the first requested profile for a duplicated target', () => { expect(resolveGatewayRestartTargets(['work', 'default'], true)).toEqual([ { targetProfile: 'default', requestedProfile: 'work' }, ]) }) it('falls back to the default profile for a blank name', () => { expect(resolveGatewayRestartTargets([''], false)).toEqual([ { targetProfile: 'default', requestedProfile: 'default' }, ]) }) it('stops, starts and waits for every restarted gateway', async () => { const stopGateway = vi.fn().mockResolvedValue(undefined) const startGateway = vi.fn().mockResolvedValue(undefined) const waitForGateway = vi.fn().mockResolvedValue(true) const results = await restartGatewaysForProfiles(['default', 'work'], { unified: false, stopGateway, startGateway, waitForGateway, }) expect(results).toEqual([ { profile: 'default', targetProfile: 'default', running: true }, { profile: 'work', targetProfile: 'work', running: true }, ]) expect(stopGateway).toHaveBeenCalledTimes(2) expect(startGateway).toHaveBeenCalledTimes(2) expect(waitForGateway).toHaveBeenCalledTimes(2) }) it('restarts a shared gateway only once in unified mode', async () => { const stopGateway = vi.fn().mockResolvedValue(undefined) const startGateway = vi.fn().mockResolvedValue(undefined) const waitForGateway = vi.fn().mockResolvedValue(true) const results = await restartGatewaysForProfiles(['default', 'work'], { unified: true, stopGateway, startGateway, waitForGateway, }) expect(results).toEqual([ { profile: 'default', targetProfile: 'default', running: true }, ]) expect(stopGateway).toHaveBeenCalledTimes(1) expect(startGateway).toHaveBeenCalledTimes(1) }) it('keeps going when one gateway fails and reports the error', async () => { const stopGateway = vi.fn() .mockResolvedValueOnce(undefined) .mockRejectedValueOnce(new Error('stop failed')) const startGateway = vi.fn().mockResolvedValue(undefined) const waitForGateway = vi.fn().mockResolvedValue(true) const results = await restartGatewaysForProfiles(['default', 'work'], { unified: false, stopGateway, startGateway, waitForGateway, }) expect(results).toEqual([ { profile: 'default', targetProfile: 'default', running: true }, { profile: 'work', targetProfile: 'work', running: false, error: 'stop failed' }, ]) }) it('reports a gateway that never reports running as failed', async () => { const stopGateway = vi.fn().mockResolvedValue(undefined) const startGateway = vi.fn().mockResolvedValue(undefined) const waitForGateway = vi.fn().mockResolvedValue(false) const results = await restartGatewaysForProfiles(['default'], { unified: false, stopGateway, startGateway, waitForGateway, }) expect(results[0]?.running).toBe(false) expect(results[0]?.error).toContain('did not report running') }) })