widgetdc-cortex / apps /backend /src /tests /graphrag.integration.test.ts
Kraft102's picture
Initial deployment - WidgeTDC Cortex Backend v2.1.0
529090e
import { describe, test, expect, beforeAll, afterAll } from 'vitest';
import { neo4jService } from '../database/Neo4jService';
import { graphMemoryService } from '../memory/GraphMemoryService';
const shouldRunNeo4jTests = process.env.RUN_NEO4J_TESTS === 'true';
const describeGraphRag = shouldRunNeo4jTests ? describe : describe.skip;
let neo4jAvailable = false;
describeGraphRag('GraphRAG Integration Tests', () => {
beforeAll(async () => {
if (!shouldRunNeo4jTests) {
neo4jAvailable = false;
return;
}
try {
await neo4jService.connect();
neo4jAvailable = await neo4jService.healthCheck();
} catch {
neo4jAvailable = false;
console.log('⚠️ Neo4j not available - GraphRAG tests will be skipped');
}
});
afterAll(async () => {
if (neo4jAvailable) {
try {
await neo4jService.runQuery('MATCH (n:TestEntity) DETACH DELETE n');
} catch { /* ignore cleanup errors */ }
await neo4jService.disconnect();
}
});
test('should create entity and retrieve it', async () => {
const entity = await graphMemoryService.createEntity(
'TestEntity',
'Test Person',
{ role: 'developer', team: 'backend' }
);
expect(entity.id).toBeDefined();
expect(entity.name).toBe('Test Person');
expect(entity.type).toBe('TestEntity');
const retrieved = await neo4jService.getNodeById(entity.id);
expect(retrieved).toBeDefined();
expect(retrieved?.properties.role).toBe('developer');
});
test('should create relation between entities', async () => {
const person = await graphMemoryService.createEntity('TestEntity', 'Alice', {});
const project = await graphMemoryService.createEntity('TestEntity', 'Project X', {});
const relation = await graphMemoryService.createRelation(
person.id,
project.id,
'WORKS_ON',
{ since: '2025-01-01' }
);
expect(relation.id).toBeDefined();
expect(relation.type).toBe('WORKS_ON');
expect(relation.sourceId).toBe(person.id);
expect(relation.targetId).toBe(project.id);
});
test('should search entities by name', async () => {
await graphMemoryService.createEntity('TestEntity', 'Bob Smith', { role: 'designer' });
await graphMemoryService.createEntity('TestEntity', 'Bob Jones', { role: 'developer' });
const results = await graphMemoryService.searchEntities('Bob');
expect(results.length).toBeGreaterThanOrEqual(2);
expect(results.some(e => e.name.includes('Bob'))).toBe(true);
});
test('should get related entities', async () => {
const alice = await graphMemoryService.createEntity('TestEntity', 'Alice', {});
const bob = await graphMemoryService.createEntity('TestEntity', 'Bob', {});
const charlie = await graphMemoryService.createEntity('TestEntity', 'Charlie', {});
await graphMemoryService.createRelation(alice.id, bob.id, 'KNOWS');
await graphMemoryService.createRelation(alice.id, charlie.id, 'KNOWS');
const related = await graphMemoryService.getRelatedEntities(alice.id);
expect(related.length).toBe(2);
expect(related.some(e => e.name === 'Bob')).toBe(true);
expect(related.some(e => e.name === 'Charlie')).toBe(true);
});
test('should find path between entities', async () => {
const a = await graphMemoryService.createEntity('TestEntity', 'A', {});
const b = await graphMemoryService.createEntity('TestEntity', 'B', {});
const c = await graphMemoryService.createEntity('TestEntity', 'C', {});
await graphMemoryService.createRelation(a.id, b.id, 'CONNECTS');
await graphMemoryService.createRelation(b.id, c.id, 'CONNECTS');
const path = await graphMemoryService.findPath(a.id, c.id);
expect(path).toBeDefined();
expect(path?.path.length).toBe(3); // A -> B -> C
expect(path?.relations.length).toBe(2);
});
test('should get graph statistics', async () => {
const stats = await graphMemoryService.getStatistics();
expect(stats.totalEntities).toBeGreaterThan(0);
expect(stats.entityTypes).toBeDefined();
expect(stats.relationTypes).toBeDefined();
});
test('should update entity properties', async () => {
const entity = await graphMemoryService.createEntity('TestEntity', 'Test', { version: 1 });
const updated = await graphMemoryService.updateEntity(entity.id, { version: 2, status: 'active' });
expect(updated).toBeDefined();
expect(updated?.properties.version).toBe(2);
expect(updated?.properties.status).toBe('active');
});
test('should delete entity and its relations', async () => {
const entity = await graphMemoryService.createEntity('TestEntity', 'ToDelete', {});
const other = await graphMemoryService.createEntity('TestEntity', 'Other', {});
await graphMemoryService.createRelation(entity.id, other.id, 'TEMP');
await graphMemoryService.deleteEntity(entity.id);
const retrieved = await neo4jService.getNodeById(entity.id);
expect(retrieved).toBeNull();
});
});
export { };