UNPKG

@wearesage/schema

Version:

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

197 lines (162 loc) 6.77 kB
import "reflect-metadata"; import { UniversalEntityService, EntityContext } from "../../services/UniversalEntityService"; import { TestConversation } from "../test-entities/TestConversation"; import { TestMessage } from "../test-entities/TestMessage"; import { TestUser } from "../test-entities/TestUser"; describe("UniversalEntityService Relationships", () => { let service: UniversalEntityService; let userContext: EntityContext; beforeEach(() => { service = UniversalEntityService.getInstance(); service.registerEntities([TestUser, TestConversation, TestMessage]); userContext = { user: { id: 'user123', username: 'testuser', email: 'test@example.com', role: 0, permissions: ['user'] } }; }); afterAll(async () => { if ((service as any).adapter && (service as any).adapter.close) { await (service as any).adapter.close(); } }); describe("Entity Creation with Relationships", () => { test("should create conversation and message with relationship", async () => { // Create conversation const conversation = await service.create(TestConversation, { name: 'Test Conversation', messageCount: 0 }, userContext); console.log('✅ Created conversation:', conversation.id); // Create message with conversation relationship const message = await service.create(TestMessage, { content: 'Hello world', role: 'user', messageIndex: 0, conversation: conversation // 🔥 THIS IS THE CRITICAL RELATIONSHIP! }, userContext); console.log('✅ Created message:', message.id); console.log('🔍 Message conversation:', message.conversation); // Verify the relationship exists expect(message.conversation).toBeDefined(); expect(message.conversation.id).toBe(conversation.id); }); test("should create message with conversation ID reference", async () => { // Create conversation const conversation = await service.create(TestConversation, { name: 'Test Conversation', messageCount: 0 }, userContext); // Create message with conversation ID (how our ingestion works) const message = await service.create(TestMessage, { content: 'Hello world', role: 'user', messageIndex: 0, conversation: conversation // 🔥 Pass full conversation object }, userContext); console.log('✅ Created message with ID reference:', message.id); console.log('🔍 Message conversation:', message.conversation); // Verify the relationship exists expect(message.conversation).toBeDefined(); expect(message.conversation.id).toBe(conversation.id); }); }); describe("Relationship Querying", () => { let conversation: TestConversation; let message1: TestMessage; let message2: TestMessage; beforeEach(async () => { // Create test data conversation = await service.create(TestConversation, { name: 'Test Conversation', messageCount: 2 }, userContext); message1 = await service.create(TestMessage, { content: 'First message', role: 'user', messageIndex: 0, conversation: conversation }, userContext); message2 = await service.create(TestMessage, { content: 'Second message', role: 'assistant', messageIndex: 1, conversation: conversation }, userContext); }); test("should query messages by conversation", async () => { // Query all messages for this conversation const messages = await service.findAll(TestMessage, { conversation: conversation.id }, userContext); console.log('🔍 Found messages:', messages.length); console.log('📄 Message contents:', messages.map(m => m.content)); expect(messages).toHaveLength(2); expect(messages[0].conversation.id).toBe(conversation.id); expect(messages[1].conversation.id).toBe(conversation.id); }); test("should load related messages for conversation", async () => { // Load the conversation with its messages const loadedConversation = await service.findById(TestConversation, conversation.id, userContext); expect(loadedConversation).toBeDefined(); // Try to load related messages try { const relatedMessages = await service.loadRelated(TestConversation, conversation.id, 'messages', userContext); console.log('🔍 Related messages:', relatedMessages.length); expect(relatedMessages).toHaveLength(2); expect((relatedMessages[0] as any).content).toBeDefined(); } catch (error) { console.error('❌ Failed to load related messages:', error); throw error; } }); }); describe("Neo4j Direct Relationship Verification", () => { test("should verify relationships exist in Neo4j", async () => { // Create conversation and message const conversation = await service.create(TestConversation, { name: 'Neo4j Test Conversation', messageCount: 1 }, userContext); const message = await service.create(TestMessage, { content: 'Neo4j test message', role: 'user', messageIndex: 0, conversation: conversation }, userContext); // Check if Neo4j has the relationship const neo4jAdapter = (service as any).adapter; if (neo4jAdapter.type === 'neo4j') { const relationshipQuery = ` MATCH (m:TestMessage {id: $messageId})-[r]->(c:TestConversation {id: $conversationId}) RETURN type(r) as relationshipType, count(r) as relationshipCount `; const result = await neo4jAdapter.runNativeQuery(relationshipQuery, { messageId: message.id, conversationId: conversation.id }); console.log('🔍 Neo4j relationship result:', result); expect(result).toBeDefined(); // We expect to find at least one relationship expect(result.relationshipCount).toBeGreaterThan(0); } }); test("should count total relationships in Neo4j", async () => { const neo4jAdapter = (service as any).adapter; if (neo4jAdapter.type === 'neo4j') { const relationshipCountQuery = ` MATCH ()-[r]->() RETURN count(r) as totalRelationships `; const result = await neo4jAdapter.runNativeQuery(relationshipCountQuery); console.log('🔍 Total relationships in Neo4j:', result); // We should have SOME relationships if our entities are connected expect(result.totalRelationships).toBeGreaterThan(0); } }); }); });