test: fix failing tests for mocks and API return types (#366)
* fix(chat): isolate concurrent session events by refactoring WebSocket event handling Refactored the WebSocket event handling mechanism to use global listeners with session-specific event routing instead of per-session listeners. This prevents event cross-talk when multiple chat sessions run concurrently. Key changes: - Client: Added sessionEventHandlers Map to route events to appropriate sessions - Client: Registered global listeners once per socket connection - Server: Extracted message processing logic into handleMessage method - Server: Improved Hermes session ID tracking with dedicated Map - Server: Added replaceByHermesSessionId for targeted message replacement Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: fix failing tests for mocks and API return types - Fixed sessions-routes.test.ts: added missing setWorkspace and listWorkspaceFolders mocks - Fixed usage-store.test.ts: removed test for non-existent initUsageStore function - Fixed profiles-store.test.ts: corrected createProfile API return type to { success: true } - Fixed syntax error in usageStatsMock (ctx.body: → ctx.body =) All tests now pass (314 passed | 2 skipped). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -52,16 +52,16 @@ describe('Profiles Store', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('createProfile calls API and refreshes list', async () => {
|
it('createProfile calls API and refreshes list', async () => {
|
||||||
mockProfilesApi.createProfile.mockResolvedValue(true)
|
mockProfilesApi.createProfile.mockResolvedValue({ success: true })
|
||||||
mockProfilesApi.fetchProfiles.mockResolvedValue([
|
mockProfilesApi.fetchProfiles.mockResolvedValue([
|
||||||
{ name: 'default', active: true, model: 'gpt-4', gateway: 'running', alias: '' },
|
{ name: 'default', active: true, model: 'gpt-4', gateway: 'running', alias: '' },
|
||||||
{ name: 'new-profile', active: false, model: 'gpt-4', gateway: 'stopped', alias: '' },
|
{ name: 'new-profile', active: false, model: 'gpt-4', gateway: 'stopped', alias: '' },
|
||||||
])
|
])
|
||||||
|
|
||||||
const store = useProfilesStore()
|
const store = useProfilesStore()
|
||||||
const ok = await store.createProfile('new-profile', false)
|
const result = await store.createProfile('new-profile', false)
|
||||||
|
|
||||||
expect(ok).toBe(true)
|
expect(result.success).toBe(true)
|
||||||
expect(mockProfilesApi.createProfile).toHaveBeenCalledWith('new-profile', false)
|
expect(mockProfilesApi.createProfile).toHaveBeenCalledWith('new-profile', false)
|
||||||
expect(store.profiles).toHaveLength(2)
|
expect(store.profiles).toHaveLength(2)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ const searchMock = vi.fn(async (ctx: any) => { ctx.body = { results: [{ id: 'sea
|
|||||||
const getMock = vi.fn(async (ctx: any) => { ctx.body = { session: { id: ctx.params.id } } })
|
const getMock = vi.fn(async (ctx: any) => { ctx.body = { session: { id: ctx.params.id } } })
|
||||||
const removeMock = vi.fn(async (ctx: any) => { ctx.body = { ok: true } })
|
const removeMock = vi.fn(async (ctx: any) => { ctx.body = { ok: true } })
|
||||||
const renameMock = vi.fn(async (ctx: any) => { ctx.body = { ok: true } })
|
const renameMock = vi.fn(async (ctx: any) => { ctx.body = { ok: true } })
|
||||||
|
const setWorkspaceMock = vi.fn(async (ctx: any) => { ctx.body = { ok: true } })
|
||||||
|
const listWorkspaceFoldersMock = vi.fn(async (ctx: any) => { ctx.body = { folders: [] } })
|
||||||
const usageBatchMock = vi.fn(async (ctx: any) => { ctx.body = {} })
|
const usageBatchMock = vi.fn(async (ctx: any) => { ctx.body = {} })
|
||||||
const usageSingleMock = vi.fn(async (ctx: any) => { ctx.body = { input_tokens: 0, output_tokens: 0 } })
|
const usageSingleMock = vi.fn(async (ctx: any) => { ctx.body = { input_tokens: 0, output_tokens: 0 } })
|
||||||
const usageStatsMock = vi.fn(async (ctx: any) => { ctx.body = { total_input_tokens: 0, total_output_tokens: 0 } })
|
const usageStatsMock = vi.fn(async (ctx: any) => { ctx.body = { total_input_tokens: 0, total_output_tokens: 0 } })
|
||||||
@@ -22,6 +24,8 @@ vi.mock('../../packages/server/src/controllers/hermes/sessions', () => ({
|
|||||||
get: getMock,
|
get: getMock,
|
||||||
remove: removeMock,
|
remove: removeMock,
|
||||||
rename: renameMock,
|
rename: renameMock,
|
||||||
|
setWorkspace: setWorkspaceMock,
|
||||||
|
listWorkspaceFolders: listWorkspaceFoldersMock,
|
||||||
usageBatch: usageBatchMock,
|
usageBatch: usageBatchMock,
|
||||||
usageSingle: usageSingleMock,
|
usageSingle: usageSingleMock,
|
||||||
usageStats: usageStatsMock,
|
usageStats: usageStatsMock,
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ vi.mock('../../packages/server/src/db/index', () => ({
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
import {
|
import {
|
||||||
initUsageStore,
|
|
||||||
updateUsage,
|
updateUsage,
|
||||||
getUsage,
|
getUsage,
|
||||||
getUsageBatch,
|
getUsageBatch,
|
||||||
@@ -32,12 +31,6 @@ describe('Usage Store (JSON fallback)', () => {
|
|||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('initUsageStore calls ensureTable when SQLite is available', () => {
|
|
||||||
// In our mock, isSqliteAvailable returns false, so ensureTable should NOT be called
|
|
||||||
initUsageStore()
|
|
||||||
expect(mockEnsureTable).not.toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('updateUsage writes via jsonSet', () => {
|
it('updateUsage writes via jsonSet', () => {
|
||||||
updateUsage('session-1', { inputTokens: 100, outputTokens: 50 })
|
updateUsage('session-1', { inputTokens: 100, outputTokens: 50 })
|
||||||
expect(mockJsonSet).toHaveBeenCalledWith(
|
expect(mockJsonSet).toHaveBeenCalledWith(
|
||||||
|
|||||||
Reference in New Issue
Block a user