UNPKG

@wearesage/schema

Version:

A flexible schema definition and validation system for TypeScript with multi-database support

289 lines (246 loc) 9.92 kB
import "reflect-metadata"; import { universalEntityService } from './services/index'; import { MetadataLayerAdapter } from './adapters/metadata-layer'; import { Neo4jAdapter } from './adapters/neo4j'; import { PostgreSQLAdapter } from './adapters/postgresql'; // Import copied entities with full complexity import { User } from './test-entities/User'; import { Message } from './test-entities/Message'; import { Conversation } from './test-entities/Conversation'; import { Space } from './test-entities/Space'; describe('Full System Integration Tests', () => { let systemContext: any; beforeAll(async () => { // Register entities universalEntityService.registerEntities([User, Message, Conversation, Space]); // Create system context systemContext = { user: { id: 'test-system', username: 'test-system', email: 'test@system.com', role: 999, permissions: ['admin', 'user'] }, requestId: 'test-' + Date.now() }; }); describe('1. Basic Entity Creation', () => { let testUser: any; let testSpace: any; test('should create a User entity', async () => { testUser = await universalEntityService.create(User, { name: 'Test User', email: 'test@example.com', status: 'active' }, systemContext); expect(testUser).toBeDefined(); expect(testUser.id).toBeDefined(); expect(testUser.name).toBe('Test User'); expect(testUser.email).toBe('test@example.com'); }); test('should create a Space entity', async () => { testSpace = await universalEntityService.create(Space, { name: 'Test Space', spaceType: 'chat', visibility: 'private', ownedByType: 'user', ownedById: testUser.id, participants: [testUser] }, systemContext); expect(testSpace).toBeDefined(); expect(testSpace.id).toBeDefined(); expect(testSpace.name).toBe('Test Space'); expect(testSpace.spaceType).toBe('chat'); }); }); describe('2. Conversation Entity (extends Space)', () => { let testUser: any; let testConversation: any; beforeAll(async () => { testUser = await universalEntityService.create(User, { name: 'Conversation Test User', email: 'conv@example.com', status: 'active' }, systemContext); }); test('should create a Conversation entity with all required properties', async () => { testConversation = await universalEntityService.create(Conversation, { // Space properties name: 'Test Conversation', spaceType: 'chat', visibility: 'private', ownedByType: 'user', ownedById: testUser.id, participants: [testUser], // Conversation-specific properties model: 'test-model', temperature: 0.7, conversationType: 'chat', status: 'active' }, systemContext); expect(testConversation).toBeDefined(); expect(testConversation.id).toBeDefined(); expect(testConversation.model).toBe('test-model'); expect(testConversation.temperature).toBe(0.7); expect(testConversation.conversationType).toBe('chat'); }); }); describe('3. Message-Conversation Relationships', () => { let testUser: any; let testConversation: any; let testMessage: any; beforeAll(async () => { testUser = await universalEntityService.create(User, { name: 'Message Test User', email: 'msg@example.com', status: 'active' }, systemContext); testConversation = await universalEntityService.create(Conversation, { name: 'Message Test Conversation', spaceType: 'chat', visibility: 'private', ownedByType: 'user', ownedById: testUser.id, participants: [testUser], model: 'test-model', temperature: 0.7, conversationType: 'chat', status: 'active' }, systemContext); }); test('should create a Message with conversation relationship', async () => { testMessage = await universalEntityService.create(Message, { content: 'Hello, this is a test message with embeddings!', role: 'user', messageIndex: 0, conversation: testConversation, // Full object relationship sender: { type: 'human', id: testUser.id, displayName: 'Test User' } }, systemContext); expect(testMessage).toBeDefined(); expect(testMessage.id).toBeDefined(); expect(testMessage.content).toBe('Hello, this is a test message with embeddings!'); expect(testMessage.role).toBe('user'); expect(testMessage.messageIndex).toBe(0); }); test('should create a Message with conversation object reference', async () => { const message2 = await universalEntityService.create(Message, { content: 'Second message with conversation object', role: 'assistant', messageIndex: 1, conversation: testConversation, // Full object reference sender: { type: 'ai', id: 'test-ai', displayName: 'Test AI' } }, systemContext); expect(message2).toBeDefined(); expect(message2.content).toBe('Second message with conversation object'); expect(message2.role).toBe('assistant'); }); }); describe('4. Embeddings Generation', () => { let testUser: any; let testConversation: any; let testMessage: any; beforeAll(async () => { testUser = await universalEntityService.create(User, { name: 'Embeddings Test User', email: 'embed@example.com', status: 'active' }, systemContext); testConversation = await universalEntityService.create(Conversation, { name: 'Embeddings Test Conversation', spaceType: 'chat', visibility: 'private', ownedByType: 'user', ownedById: testUser.id, participants: [testUser], model: 'test-model', temperature: 0.7, conversationType: 'chat', status: 'active' }, systemContext); }); test('should generate embeddings for Message content', async () => { const consoleSpy = jest.spyOn(console, 'log'); testMessage = await universalEntityService.create(Message, { content: 'This message should generate embeddings for semantic search!', role: 'user', messageIndex: 0, conversation: testConversation, thinking: 'Some AI thinking process here...', sender: { type: 'human', id: testUser.id, displayName: 'Test User' } }, systemContext); // Check if embeddings generation was logged expect(consoleSpy).toHaveBeenCalledWith('🧠 Generated embeddings for entity'); // Check if contentEmbedding field exists (from @Embeddings decorator) expect((testMessage as any).contentEmbedding).toBeDefined(); consoleSpy.mockRestore(); }); test('should generate embeddings for Conversation', async () => { const consoleSpy = jest.spyOn(console, 'log'); const conv = await universalEntityService.create(Conversation, { name: 'Conversation with semantic embedding', spaceType: 'chat', visibility: 'private', ownedByType: 'user', ownedById: testUser.id, participants: [testUser], model: 'test-model', temperature: 0.7, conversationType: 'chat', status: 'active', systemPrompt: 'You are a helpful AI assistant focused on testing embeddings.' }, systemContext); // Check if embeddings generation was logged expect(consoleSpy).toHaveBeenCalledWith('🧠 Generated embeddings for entity'); // Check if semanticEmbedding field exists (from @Embeddings decorator) expect((conv as any).semanticEmbedding).toBeDefined(); consoleSpy.mockRestore(); }); }); describe('5. Metadata Layer Functionality', () => { test('should create PostgreSQL metadata tables', async () => { // This test will check if PostgreSQL metadata tables are created // Tables should be created based on @PostgresMetadata decorators // We expect tables like: // - message_metadata (from Message entity) // - conversation_metadata (from Conversation entity) // Note: This will be verified by checking actual PostgreSQL tables expect(true).toBe(true); // Placeholder - will be verified by observing behavior }); test('should store metadata in PostgreSQL lookup tables', async () => { // This test verifies that metadata is actually being stored in PostgreSQL // as lookup tables for the Neo4j graph data expect(true).toBe(true); // Placeholder - will be verified by checking PostgreSQL }); }); describe('6. Neo4j Relationship Verification', () => { test('should create BELONGS_TO relationships in Neo4j', async () => { // This test verifies that Message -> BELONGS_TO -> Conversation relationships // are actually created in the Neo4j graph database expect(true).toBe(true); // Placeholder - will be verified by checking Neo4j }); }); describe('7. Adapter Configuration Verification', () => { test('should be using MetadataLayerAdapter (not just Neo4jAdapter)', async () => { // Verify that the system is actually using the MetadataLayerAdapter // which wraps Neo4j + PostgreSQL + Embeddings const service = universalEntityService as any; const adapter = service.adapter; expect(adapter).toBeInstanceOf(MetadataLayerAdapter); expect(adapter.primaryAdapter).toBeInstanceOf(Neo4jAdapter); expect(adapter.metadataAdapter).toBeInstanceOf(PostgreSQLAdapter); }); }); });