Files
waggle-os/packages/hive-mind-core/tests/mind/sessions-hive-mind.test.ts
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

97 lines
3.3 KiB
TypeScript

/**
* SessionStore tests — full-file port from
* hive-mind/packages/core/src/mind/sessions.test.ts.
*
* Memory Sync Repair Step 2. Source: hive-mind file at HEAD c363257.
*
* Filename suffix `-hive-mind` keeps this distinct from waggle-os's
* own `sessions.test.ts` (which focuses on `ensureActive` semantics
* for the agent loop). The hive-mind file covers create/close/archive/
* ensure/getByProject + ensureActive — broader API surface coverage.
*
* Adapted imports: `./db.js`, `./sessions.js` → `../../src/mind/...`.
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { rmSync, existsSync } from 'node:fs';
import { MindDB } from '../../src/mind/db.js';
import { SessionStore } from '../../src/mind/sessions.js';
describe('SessionStore (hive-mind port)', () => {
let dbPath: string;
let db: MindDB;
let sessions: SessionStore;
beforeEach(() => {
dbPath = join(tmpdir(), `waggle-mind-sessions-test-${Date.now()}-${Math.random()}.mind`);
db = new MindDB(dbPath);
sessions = new SessionStore(db);
});
afterEach(() => {
db.close();
if (existsSync(dbPath)) rmSync(dbPath);
for (const suffix of ['-shm', '-wal']) {
if (existsSync(dbPath + suffix)) rmSync(dbPath + suffix);
}
});
it('create() produces an active session with a unique gop_id', () => {
const a = sessions.create('project-x');
const b = sessions.create('project-x');
expect(a.status).toBe('active');
expect(b.status).toBe('active');
expect(a.gop_id).not.toBe(b.gop_id);
expect(a.project_id).toBe('project-x');
expect(a.ended_at).toBeNull();
});
it('close() transitions status and sets ended_at + summary', () => {
const s = sessions.create();
const closed = sessions.close(s.gop_id, 'summary-text');
expect(closed.status).toBe('closed');
expect(closed.ended_at).not.toBeNull();
expect(closed.summary).toBe('summary-text');
});
it('archive() transitions status without touching ended_at', () => {
const s = sessions.create();
const archived = sessions.archive(s.gop_id);
expect(archived.status).toBe('archived');
});
it('ensureActive() returns the existing active session or creates a new one', () => {
const first = sessions.ensureActive('p1');
expect(first.status).toBe('active');
const second = sessions.ensureActive('p1');
expect(second.id).toBe(first.id);
expect(second.gop_id).toBe(first.gop_id);
sessions.close(first.gop_id);
const third = sessions.ensureActive('p1');
expect(third.id).not.toBe(first.id);
expect(third.status).toBe('active');
});
it('ensure() is idempotent for a stable gop_id', () => {
const a = sessions.ensure('harvest', undefined, 'long-lived harvest session');
const b = sessions.ensure('harvest');
expect(a.id).toBe(b.id);
expect(a.summary).toBe('long-lived harvest session');
expect(b.summary).toBe('long-lived harvest session');
});
it('getByProject() returns sessions sorted newest-first', () => {
const a = sessions.create('proj');
sessions.close(a.gop_id);
const b = sessions.create('proj');
const list = sessions.getByProject('proj');
expect(list).toHaveLength(2);
expect(list[0].id).toBe(b.id);
expect(list[1].id).toBe(a.id);
});
});