Squashed 'vendor/ruvector/' content from commit b64c2172

git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
commit d803bfe2b1
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,410 @@
/**
* PostgreSQL Persistence - Integration Tests
*
* Tests for database operations, transactions, and data integrity
*/
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { createMockPool, queryBuilderHelpers, type MockPool } from '../../mocks/postgres.mock';
import { createAgent, createSession, createMemory, createTenant } from '../../factories';
describe('PostgreSQL Persistence', () => {
let pool: MockPool;
beforeEach(async () => {
pool = createMockPool();
await pool.connect();
});
afterEach(async () => {
await pool.end();
});
describe('Connection Management', () => {
it('should establish connection', async () => {
expect(pool.isConnected()).toBe(true);
});
it('should close connection', async () => {
await pool.end();
expect(pool.isConnected()).toBe(false);
});
});
describe('Agent Persistence', () => {
it('should insert agent', async () => {
const agent = createAgent({ name: 'Test Agent', type: 'coder' });
const result = await pool.query(
'INSERT INTO agents (id, name, type, status, config) VALUES ($1, $2, $3, $4, $5) RETURNING *',
[agent.id, agent.name, agent.type, agent.status, JSON.stringify(agent.config)]
);
expect(result.rowCount).toBe(1);
expect(queryBuilderHelpers.expectQuery(pool, /INSERT INTO agents/)).toBe(true);
});
it('should select agent by ID', async () => {
const agent = createAgent();
// Seed data
pool.seedData('agents', [{ id: agent.id, name: agent.name, type: agent.type }]);
const result = await pool.query(
'SELECT * FROM agents WHERE id = $1',
[agent.id]
);
expect(result.rows).toHaveLength(1);
expect(result.rows[0].id).toBe(agent.id);
});
it('should update agent', async () => {
const agent = createAgent();
pool.seedData('agents', [{ id: agent.id, name: agent.name, status: 'idle' }]);
const result = await pool.query(
'UPDATE agents SET status = $1 WHERE id = $2',
['busy', agent.id]
);
expect(result.rowCount).toBe(1);
});
it('should delete agent', async () => {
const agent = createAgent();
pool.seedData('agents', [{ id: agent.id }]);
const result = await pool.query(
'DELETE FROM agents WHERE id = $1',
[agent.id]
);
expect(result.rowCount).toBe(1);
});
});
describe('Session Persistence', () => {
it('should insert session', async () => {
const session = createSession();
const result = await pool.query(
'INSERT INTO sessions (id, tenant_id, user_id, channel_id, status) VALUES ($1, $2, $3, $4, $5) RETURNING *',
[session.id, session.tenantId, session.userId, session.channelId, session.status]
);
expect(result.rowCount).toBe(1);
});
it('should select sessions by tenant', async () => {
const tenantId = 'tenant-001';
pool.seedData('sessions', [
{ id: 'session-1', tenantId, tenant_id: tenantId },
{ id: 'session-2', tenantId, tenant_id: tenantId },
{ id: 'session-3', tenantId: 'other-tenant', tenant_id: 'other-tenant' }
]);
const result = await pool.query(
'SELECT * FROM sessions WHERE tenant_id = $1',
[tenantId]
);
expect(result.rows).toHaveLength(2);
result.rows.forEach(row => {
expect(row.tenantId || row.tenant_id).toBe(tenantId);
});
});
});
describe('Memory Persistence', () => {
it('should insert memory entry', async () => {
const memory = createMemory({ key: 'test-key', value: { data: 'test' } });
const result = await pool.query(
'INSERT INTO memories (id, tenant_id, key, value, type) VALUES ($1, $2, $3, $4, $5) RETURNING *',
[memory.id, memory.tenantId, memory.key, JSON.stringify(memory.value), memory.type]
);
expect(result.rowCount).toBe(1);
});
it('should select memory by key', async () => {
pool.seedData('memories', [
{ id: 'mem-1', key: 'unique-key', tenantId: 'tenant-001' }
]);
// Note: Mock implementation uses indexByKey
const result = await pool.query(
'SELECT * FROM memories WHERE key = $1',
['unique-key']
);
expect(queryBuilderHelpers.expectQuery(pool, /SELECT \* FROM memories/)).toBe(true);
});
});
describe('Tenant Persistence', () => {
it('should insert tenant', async () => {
const tenant = createTenant();
const result = await pool.query(
'INSERT INTO tenants (id, name, slack_team_id, status, plan) VALUES ($1, $2, $3, $4, $5) RETURNING *',
[tenant.id, tenant.name, tenant.slackTeamId, tenant.status, tenant.plan]
);
expect(result.rowCount).toBe(1);
});
it('should select tenant by slack team ID', async () => {
pool.seedData('tenants', [
{ id: 'tenant-1', slackTeamId: 'T12345678' }
]);
const result = await pool.query(
'SELECT * FROM tenants WHERE id = $1',
['tenant-1']
);
expect(result.rows).toHaveLength(1);
});
});
describe('Transactions', () => {
it('should execute transaction with commit', async () => {
await pool.query('BEGIN');
await pool.query('INSERT INTO agents (id, name) VALUES ($1, $2)', ['agent-1', 'Test']);
await pool.query('INSERT INTO sessions (id, tenant_id) VALUES ($1, $2)', ['session-1', 'tenant-1']);
await pool.query('COMMIT');
expect(queryBuilderHelpers.expectTransaction(pool)).toBe(true);
});
it('should execute transaction with rollback', async () => {
await pool.query('BEGIN');
await pool.query('INSERT INTO agents (id, name) VALUES ($1, $2)', ['agent-1', 'Test']);
await pool.query('ROLLBACK');
expect(queryBuilderHelpers.expectTransaction(pool)).toBe(true);
});
});
describe('Query Logging', () => {
it('should log all queries', async () => {
await pool.query('SELECT 1');
await pool.query('SELECT 2');
await pool.query('SELECT 3');
const log = pool.getQueryLog();
expect(log).toHaveLength(3);
});
it('should log query values', async () => {
await pool.query('INSERT INTO agents (id) VALUES ($1)', ['agent-1']);
const log = pool.getQueryLog();
expect(log[0].values).toEqual(['agent-1']);
});
it('should clear query log', async () => {
await pool.query('SELECT 1');
pool.clearQueryLog();
expect(pool.getQueryLog()).toHaveLength(0);
});
});
describe('Query Helpers', () => {
it('should match query patterns', async () => {
await pool.query('SELECT * FROM agents WHERE type = $1', ['coder']);
expect(queryBuilderHelpers.expectQuery(pool, /SELECT \* FROM agents/)).toBe(true);
expect(queryBuilderHelpers.expectQuery(pool, /SELECT \* FROM sessions/)).toBe(false);
});
it('should count matching queries', async () => {
await pool.query('SELECT * FROM agents');
await pool.query('SELECT * FROM agents WHERE id = $1', ['1']);
await pool.query('SELECT * FROM sessions');
const count = queryBuilderHelpers.expectQueryCount(pool, /SELECT \* FROM agents/);
expect(count).toBe(2);
});
});
});
describe('PostgreSQL Repository Patterns', () => {
let pool: MockPool;
beforeEach(async () => {
pool = createMockPool();
await pool.connect();
});
afterEach(async () => {
await pool.end();
});
describe('Bulk Operations', () => {
it('should handle bulk insert', async () => {
const agents = Array.from({ length: 10 }, (_, i) =>
createAgent({ id: `agent-${i}`, name: `Agent ${i}` })
);
// Simulate bulk insert
for (const agent of agents) {
await pool.query(
'INSERT INTO agents (id, name) VALUES ($1, $2)',
[agent.id, agent.name]
);
}
expect(queryBuilderHelpers.expectQueryCount(pool, /INSERT INTO agents/)).toBe(10);
});
});
describe('Upsert Operations', () => {
it('should handle upsert pattern', async () => {
pool.seedData('agents', [{ id: 'agent-1', name: 'Original' }]);
// Simulate upsert
const result = await pool.query(
`INSERT INTO agents (id, name) VALUES ($1, $2)
ON CONFLICT (id) DO UPDATE SET name = $2
RETURNING *`,
['agent-1', 'Updated']
);
expect(queryBuilderHelpers.expectQuery(pool, /INSERT INTO agents/)).toBe(true);
});
});
describe('Pagination', () => {
it('should handle paginated queries', async () => {
pool.seedData('agents', Array.from({ length: 25 }, (_, i) => ({
id: `agent-${i}`,
name: `Agent ${i}`
})));
const page1 = await pool.query(
'SELECT * FROM agents ORDER BY id LIMIT $1 OFFSET $2',
[10, 0]
);
const page2 = await pool.query(
'SELECT * FROM agents ORDER BY id LIMIT $1 OFFSET $2',
[10, 10]
);
expect(queryBuilderHelpers.expectQueryCount(pool, /LIMIT/)).toBe(2);
});
});
describe('Join Operations', () => {
it('should log join queries', async () => {
await pool.query(`
SELECT s.*, a.name as agent_name
FROM sessions s
LEFT JOIN agents a ON a.id = ANY(s.active_agents)
WHERE s.tenant_id = $1
`, ['tenant-1']);
expect(queryBuilderHelpers.expectQuery(pool, /JOIN/)).toBe(true);
});
});
describe('Aggregations', () => {
it('should log aggregation queries', async () => {
await pool.query(`
SELECT tenant_id, COUNT(*) as session_count
FROM sessions
GROUP BY tenant_id
HAVING COUNT(*) > $1
`, [5]);
expect(queryBuilderHelpers.expectQuery(pool, /GROUP BY/)).toBe(true);
expect(queryBuilderHelpers.expectQuery(pool, /COUNT/)).toBe(true);
});
});
});
describe('PostgreSQL Error Handling', () => {
let pool: MockPool;
beforeEach(async () => {
pool = createMockPool();
await pool.connect();
});
afterEach(async () => {
await pool.end();
});
it('should handle query errors gracefully', async () => {
// In real implementation, this would test actual error scenarios
const result = await pool.query('SELECT * FROM non_existent_table');
expect(result.rows).toEqual([]);
});
it('should track failed transactions', async () => {
await pool.query('BEGIN');
await pool.query('INVALID SQL THAT WOULD FAIL');
await pool.query('ROLLBACK');
expect(queryBuilderHelpers.expectTransaction(pool)).toBe(true);
});
});
describe('PostgreSQL Multi-tenancy', () => {
let pool: MockPool;
beforeEach(async () => {
pool = createMockPool();
await pool.connect();
// Seed multi-tenant data
pool.seedData('agents', [
{ id: 'agent-1', tenantId: 'tenant-1', tenant_id: 'tenant-1', name: 'T1 Agent' },
{ id: 'agent-2', tenantId: 'tenant-2', tenant_id: 'tenant-2', name: 'T2 Agent' },
{ id: 'agent-3', tenantId: 'tenant-1', tenant_id: 'tenant-1', name: 'T1 Agent 2' }
]);
});
afterEach(async () => {
await pool.end();
});
it('should filter by tenant ID', async () => {
const result = await pool.query(
'SELECT * FROM agents WHERE tenant_id = $1',
['tenant-1']
);
expect(result.rows).toHaveLength(2);
result.rows.forEach(row => {
expect(row.tenantId || row.tenant_id).toBe('tenant-1');
});
});
it('should isolate tenant data', async () => {
const tenant1Data = await pool.query(
'SELECT * FROM agents WHERE tenant_id = $1',
['tenant-1']
);
const tenant2Data = await pool.query(
'SELECT * FROM agents WHERE tenant_id = $1',
['tenant-2']
);
expect(tenant1Data.rows).toHaveLength(2);
expect(tenant2Data.rows).toHaveLength(1);
// Verify no data leakage
const tenant1Ids = tenant1Data.rows.map((r: any) => r.id);
const tenant2Ids = tenant2Data.rows.map((r: any) => r.id);
expect(tenant1Ids).not.toContain('agent-2');
expect(tenant2Ids).not.toContain('agent-1');
});
});