Files
Hermes-ui/tests/server/sessions-db.test.ts
T
ekko 35481e452d fix: use dynamic import for node:sqlite with Node version guard
Replace static top-level import with runtime version check and dynamic
import() so Node < 22.5 gracefully falls back to CLI path instead of
crashing at module load time.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 09:34:59 +08:00

126 lines
3.7 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
const allMock = vi.fn()
const prepareMock = vi.fn(() => ({ all: allMock }))
const closeMock = vi.fn()
const databaseSyncMock = vi.fn(() => ({ prepare: prepareMock, close: closeMock }))
const getActiveProfileDirMock = vi.fn(() => '/tmp/hermes-profile')
vi.doMock('node:sqlite', () => ({
DatabaseSync: databaseSyncMock,
}))
vi.mock('../../packages/server/src/services/hermes/hermes-profile', () => ({
getActiveProfileDir: getActiveProfileDirMock,
}))
describe('session DB summaries', () => {
beforeEach(() => {
vi.resetModules()
allMock.mockReset()
prepareMock.mockClear()
closeMock.mockClear()
databaseSyncMock.mockClear()
getActiveProfileDirMock.mockReset()
getActiveProfileDirMock.mockReturnValue('/tmp/hermes-profile')
})
it('queries sqlite for lightweight session summaries', async () => {
allMock.mockReturnValue([
{
id: 's1',
source: 'cli',
user_id: '',
model: 'openai/gpt-5.4',
title: 'Named session',
started_at: 1710000000,
ended_at: null,
end_reason: '',
message_count: 3,
tool_call_count: 1,
input_tokens: 10,
output_tokens: 20,
cache_read_tokens: 0,
cache_write_tokens: 0,
reasoning_tokens: 0,
billing_provider: 'openrouter',
estimated_cost_usd: 0.01,
actual_cost_usd: null,
cost_status: 'estimated',
preview: 'hello world',
last_active: 1710000005,
},
])
const mod = await import('../../packages/server/src/services/hermes/sessions-db')
const rows = await mod.listSessionSummaries(undefined, 50)
expect(databaseSyncMock).toHaveBeenCalledWith('/tmp/hermes-profile/state.db', { open: true, readOnly: true })
expect(prepareMock).toHaveBeenCalledWith(expect.stringContaining("AND s.source != 'tool'"))
expect(allMock).toHaveBeenCalledWith(50)
expect(closeMock).toHaveBeenCalled()
expect(rows).toEqual([
{
id: 's1',
source: 'cli',
user_id: null,
model: 'openai/gpt-5.4',
title: 'Named session',
started_at: 1710000000,
ended_at: null,
end_reason: null,
message_count: 3,
tool_call_count: 1,
input_tokens: 10,
output_tokens: 20,
cache_read_tokens: 0,
cache_write_tokens: 0,
reasoning_tokens: 0,
billing_provider: 'openrouter',
estimated_cost_usd: 0.01,
actual_cost_usd: null,
cost_status: 'estimated',
preview: 'hello world',
last_active: 1710000005,
},
])
})
it('adds source filter and falls back last_active to started_at', async () => {
allMock.mockReturnValue([
{
id: 's2',
source: 'telegram',
user_id: '',
model: 'openai/gpt-5.4',
title: '',
started_at: 1710000100,
ended_at: null,
end_reason: '',
message_count: 1,
tool_call_count: 0,
input_tokens: 4,
output_tokens: 5,
cache_read_tokens: 0,
cache_write_tokens: 0,
reasoning_tokens: 0,
billing_provider: '',
estimated_cost_usd: 0,
actual_cost_usd: null,
cost_status: '',
preview: 'preview text',
last_active: null,
},
])
const mod = await import('../../packages/server/src/services/hermes/sessions-db')
const rows = await mod.listSessionSummaries('telegram', 2)
expect(prepareMock).toHaveBeenCalledWith(expect.stringContaining('AND s.source = ?'))
expect(allMock).toHaveBeenCalledWith('telegram', 2)
expect(rows[0].last_active).toBe(1710000100)
expect(rows[0].source).toBe('telegram')
expect(rows[0].title).toBe('preview text')
})
})