e101577d61
Task 5 do MVP Espelho: endpoint Express com factory createSessionsRouter(db) que expõe GET / (lista filtrável por days/project/tool/skill/q + limit/offset validados via Zod) e GET /:id (meta + eventos via parseSessionFile). Integrado em server.ts com DB aberta a partir de OBSERVABILIDADE_DB ?? DEFAULT_DB_PATH. Validação empírica: total=559 sessões (últimos 7d), detalhe com 37 eventos. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
2.2 KiB
TypeScript
69 lines
2.2 KiB
TypeScript
/**
|
|
* Testes da rota /api/sessions (validação Zod + integração com SessionsDb).
|
|
* @author Descomplicar® | Projecto Observabilidade (Espelho)
|
|
*/
|
|
import { describe, it, expect, beforeAll } from 'vitest'
|
|
import express from 'express'
|
|
import request from 'supertest'
|
|
import { mkdtempSync } from 'fs'
|
|
import { tmpdir } from 'os'
|
|
import { join } from 'path'
|
|
import { openSessionsDb } from '../services/sessions/db.js'
|
|
import { createSessionsRouter } from '../routes/sessions.js'
|
|
import type { SessionMeta } from '../types/session.js'
|
|
|
|
function meta(overrides: Partial<SessionMeta> = {}): SessionMeta {
|
|
return {
|
|
session_id: 's1',
|
|
project_path: '/tmp/p',
|
|
project_slug: 'p',
|
|
jsonl_path: '/tmp/p/s1.jsonl',
|
|
started_at: new Date().toISOString(),
|
|
ended_at: null,
|
|
duration_sec: 60,
|
|
event_count: 10,
|
|
user_messages: 2,
|
|
assistant_msgs: 5,
|
|
tool_calls: 3,
|
|
first_prompt: 'teste',
|
|
tools_used: ['Bash'],
|
|
skills_invoked: [],
|
|
outcome: 'completed',
|
|
permission_mode: 'default',
|
|
file_size: 1000,
|
|
indexed_at: new Date().toISOString(),
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
describe('GET /api/sessions', () => {
|
|
let app: express.Express
|
|
beforeAll(() => {
|
|
const dbPath = join(mkdtempSync(join(tmpdir(), 'obs-r-')), 'sessions.db')
|
|
const db = openSessionsDb(dbPath)
|
|
db.upsertSession(meta({ session_id: 's1', project_slug: 'alpha', jsonl_path: '/tmp/p/s1.jsonl' }))
|
|
db.upsertSession(meta({ session_id: 's2', project_slug: 'beta', jsonl_path: '/tmp/p/s2.jsonl' }))
|
|
app = express()
|
|
app.use('/api/sessions', createSessionsRouter(db))
|
|
})
|
|
|
|
it('lista todas as sessões por omissão', async () => {
|
|
const res = await request(app).get('/api/sessions')
|
|
expect(res.status).toBe(200)
|
|
expect(res.body.total).toBe(2)
|
|
expect(res.body.items).toHaveLength(2)
|
|
})
|
|
|
|
it('filtra por projecto', async () => {
|
|
const res = await request(app).get('/api/sessions').query({ project: 'alpha' })
|
|
expect(res.status).toBe(200)
|
|
expect(res.body.total).toBe(1)
|
|
expect(res.body.items[0].project_slug).toBe('alpha')
|
|
})
|
|
|
|
it('rejeita limit inválido', async () => {
|
|
const res = await request(app).get('/api/sessions').query({ limit: '9999' })
|
|
expect(res.status).toBe(400)
|
|
})
|
|
})
|