Files
hermes-web-ui/tests/server/jobs-controller.test.ts
T

68 lines
1.9 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
vi.mock('../../packages/server/src/services/gateway-bootstrap', () => ({
getGatewayManagerInstance: () => ({
getUpstream: () => 'http://127.0.0.1:8642',
getApiKey: () => null,
}),
}))
const mockFetch = vi.fn()
vi.stubGlobal('fetch', mockFetch)
import { update } from '../../packages/server/src/controllers/hermes/jobs'
function createMockCtx(overrides: Record<string, any> = {}) {
const ctx: any = {
req: { method: 'PATCH' },
request: { body: { name: 'renamed' } },
params: { id: 'abc123abc123' },
query: {},
search: '',
headers: {},
status: 200,
set: vi.fn(),
body: null,
...overrides,
}
ctx.get = (name: string) => {
const match = Object.entries(ctx.headers).find(([key]) => key.toLowerCase() === name.toLowerCase())
const value = match?.[1]
return Array.isArray(value) ? value[0] : value || ''
}
return ctx
}
describe('Hermes jobs controller proxy', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('passes through upstream validation status and body instead of masking it as 502', async () => {
mockFetch.mockResolvedValue({
ok: false,
status: 400,
statusText: 'Bad Request',
headers: new Headers({ 'content-type': 'application/json' }),
json: () => Promise.resolve({ error: 'Prompt must be ≤ 5000 characters' }),
})
const ctx = createMockCtx()
await update(ctx)
expect(ctx.status).toBe(400)
expect(ctx.body).toEqual({ error: 'Prompt must be ≤ 5000 characters' })
expect(ctx.set).toHaveBeenCalledWith('Content-Type', 'application/json')
})
it('keeps real proxy connection failures as 502', async () => {
mockFetch.mockRejectedValue(new Error('ECONNREFUSED'))
const ctx = createMockCtx()
await update(ctx)
expect(ctx.status).toBe(502)
expect(ctx.body).toEqual({ error: { message: 'Proxy error: ECONNREFUSED' } })
})
})