Files
dashlibstorage/scripts/test-modelconversation.js
2026-10-03 23:13:40 +02:00

88 lines
3.7 KiB
JavaScript

import assert from 'node:assert/strict';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import LibDashStore from '../src/index.js';
import { BetterSqlite3Provider } from '../src/providers/sqlite3/index.js';
async function run() {
console.log('--- Testing store.modelconversation / store.modelmessage ---');
const tempDir = mkdtempSync(join(tmpdir(), 'test-modelconv-'));
const provider = new BetterSqlite3Provider({
filename: join(tempDir, 'test.db'),
storageDir: join(tempDir, 'storage'),
});
await provider.initialize();
const store = await new LibDashStore(provider);
try {
const userA = await store.google_auth.add('mc-a@example.com');
const company = await store.company.create({
name: 'MC Corp', iso639: 'de', taxrate: 19, reducedtaxrate: 7, googleAuthId: userA,
});
await store.google_auth.setSelectedCompany(userA, company.id);
const conv = await store.modelconversation.create(userA, {
provider: 'openrouter', model: 'test/model',
});
assert.equal(conv.state, 'idle');
assert.equal(conv.provider, 'openrouter');
await assert.rejects(store.modelconversation.create(userA, { model: 'x' }), /Provider required/);
await assert.rejects(store.modelconversation.create(userA, { provider: 'x' }), /Model required/);
const list = await store.modelconversation.list(userA);
assert.equal(list.length, 1);
assert.deepEqual(await store.modelmessage.list(userA, conv.id), []);
const m1 = await store.modelmessage.add(userA, conv.id, { message: 'hello' });
assert.equal(m1.role, 'user');
assert.equal(m1.conversation_id, conv.id);
await assert.rejects(store.modelmessage.add(userA, conv.id, { message: ' ' }), /Message required/);
await assert.rejects(store.modelmessage.add(userA, 9999, { message: 'x' }), /Conversation not found/);
// Non-idle conversation refuses user messages but allows assistant messages
const busyConv = await store.modelconversation.setState(userA, conv.id, 'busy');
assert.equal(busyConv.state, 'busy');
const fetchedBusy = await store.modelconversation.get(userA, conv.id);
assert.equal(fetchedBusy.state, 'busy');
await assert.rejects(
store.modelmessage.add(userA, conv.id, { message: 'again' }),
/Conversation is not idle/,
);
// Assistant message can be added while busy
const mAssistant = await store.modelmessage.add(userA, conv.id, { message: 'echo: hello', role: 'assistant' });
assert.equal(mAssistant.role, 'assistant');
assert.equal(mAssistant.message, 'echo: hello');
// Back to idle
await store.modelconversation.setState(userA, conv.id, 'idle');
await store.modelmessage.add(userA, conv.id, { message: 'second' });
const msgs = await store.modelmessage.list(userA, conv.id);
assert.deepEqual(msgs.map((m) => m.message), ['hello', 'echo: hello', 'second']);
assert.deepEqual(msgs.map((m) => m.role), ['user', 'assistant', 'user']);
// Other user cannot see or write
const userB = await store.google_auth.add('mc-b@example.com');
await store.companyuser.add(company.id, userB);
await store.google_auth.setSelectedCompany(userB, company.id);
assert.equal((await store.modelconversation.list(userB)).length, 0);
await assert.rejects(store.modelmessage.list(userB, conv.id), /Conversation not found/);
await assert.rejects(store.modelmessage.add(userB, conv.id, { message: 'x' }), /Conversation not found/);
console.log('PASS');
} finally {
await provider.close?.();
rmSync(tempDir, { recursive: true, force: true });
}
}
run().catch((err) => {
console.error('FAIL', err);
process.exit(1);
});