GPU_GUARD_MONOREPO/packages/backend/test/session_tree_factory.test.ts
2026-05-20 21:39:12 +08:00

139 lines
3.8 KiB
TypeScript

import * as path from 'node:path';
import { FileSessionTreeProvider } from '../src/modules/netaclaw/session-tree/file_provider.js';
import { MySqlSessionTreeProvider } from '../src/modules/netaclaw/session-tree/mysql_provider.js';
import {
createSessionTreeProvider,
resolveAgentSessionTreeConfig,
} from '../src/modules/netaclaw/session-tree/factory.js';
describe('session-tree factory', () => {
it('creates a file provider from agent session config and netaclaw data dir defaults', () => {
const provider = createSessionTreeProvider({
session: resolveAgentSessionTreeConfig(
{
backend: 'file',
},
{
backend: 'mysql',
dataDir: 'C:/neta-data',
},
),
cwd: 'C:/workspace/neta',
});
expect(provider).toBeInstanceOf(FileSessionTreeProvider);
expect((provider as FileSessionTreeProvider).getSessionFilePath('session-1')).toBe(
path.join('C:/neta-data', 'sessions', `${Buffer.from('session-1', 'utf8').toString('base64url')}.jsonl`),
);
});
it('allows agent config to override the file session root dir', () => {
const provider = createSessionTreeProvider({
session: resolveAgentSessionTreeConfig(
{
backend: 'file',
file: {
rootDir: 'D:/custom-sessions',
},
},
{
backend: 'mysql',
dataDir: 'C:/neta-data',
},
),
cwd: 'C:/workspace/neta',
});
expect(provider).toBeInstanceOf(FileSessionTreeProvider);
expect((provider as FileSessionTreeProvider).getSessionFilePath('session-2')).toBe(
path.join('D:/custom-sessions', `${Buffer.from('session-2', 'utf8').toString('base64url')}.jsonl`),
);
});
it('creates a mysql provider when agent session backend is mysql', () => {
const sessionRepo = {
find: jest.fn(),
findOne: jest.fn(),
findOneBy: jest.fn(),
save: jest.fn(),
delete: jest.fn(),
};
const entryRepo = {
find: jest.fn(),
findOne: jest.fn(),
findOneBy: jest.fn(),
save: jest.fn(),
delete: jest.fn(),
};
const provider = createSessionTreeProvider({
session: resolveAgentSessionTreeConfig(
{
backend: 'mysql',
},
{
backend: 'file',
dataDir: 'C:/neta-data',
},
),
sessionRepo,
entryRepo,
});
expect(provider).toBeInstanceOf(MySqlSessionTreeProvider);
});
it('throws when mysql backend is selected without repositories', () => {
expect(() => createSessionTreeProvider({
session: resolveAgentSessionTreeConfig(
{
backend: 'mysql',
},
{
backend: 'file',
dataDir: 'C:/neta-data',
},
),
})).toThrow('MySqlSessionTreeProvider requires both sessionRepo and entryRepo');
});
});
describe('resolveAgentSessionTreeConfig', () => {
it('defaults to the application backend when agent config is empty', () => {
expect(resolveAgentSessionTreeConfig(undefined, {
backend: 'file',
dataDir: 'C:/neta-data',
})).toEqual({
backend: 'file',
file: {
rootDir: path.join('C:/neta-data', 'sessions'),
},
});
});
it('defaults to file backend when neither agent nor global config specifies a backend', () => {
expect(resolveAgentSessionTreeConfig(undefined, {
dataDir: 'C:/neta-data',
})).toEqual({
backend: 'file',
file: {
rootDir: path.join('C:/neta-data', 'sessions'),
},
});
});
it('keeps mysql agent config without injecting file-only options', () => {
expect(resolveAgentSessionTreeConfig(
{
backend: 'mysql',
},
{
backend: 'file',
dataDir: 'C:/neta-data',
},
)).toEqual({
backend: 'mysql',
});
});
});