139 lines
3.8 KiB
TypeScript
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',
|
|
});
|
|
});
|
|
});
|