@wearesage/schema
Version:
A flexible schema definition and validation system for TypeScript with multi-database support
168 lines (136 loc) • 5.24 kB
text/typescript
import { Neo4jAdapter } from '../../adapters/neo4j';
import { MetadataRegistry } from '../../core/MetadataRegistry';
import { Entity, Property, Id, Labels, ManyToOne, ManyToMany } from '../../core/decorators';
import { TestRegistryProvider } from '../../core/TestRegistryProvider';
describe('Neo4jAdapter - Dynamic Imports', () => {
let adapter: Neo4jAdapter;
let registry: MetadataRegistry;
beforeEach(() => {
// Use test registry provider
const testProvider = new TestRegistryProvider();
registry = testProvider.getRegistry();
adapter = new Neo4jAdapter(registry, 'bolt://localhost:7687');
});
// Test entities with dynamic imports (like our real entities)
()
(['User'])
class TestUser {
()
id!: string;
()
name!: string;
()
email!: string;
}
()
(['Space'])
class TestSpace {
()
id!: string;
()
name!: string;
()
spaceType!: string;
// Dynamic import relationship (this is what's failing)
({ target: () => TestUser, inverse: 'ownedSpaces' })
owner?: TestUser;
// Dynamic import many-to-many relationship
({ target: () => TestUser, inverse: 'participatingSpaces' })
participants!: TestUser[];
}
describe('Dynamic Import Relationships', () => {
it('should handle ManyToOne relationships with function targets', async () => {
// Register entities
registry.registerEntity(TestUser);
registry.registerEntity(TestSpace);
// Create a user
const user = new TestUser();
user.id = 'user-1';
user.name = 'Test User';
user.email = 'test@example.com';
// Create a space with the user as owner
const space = new TestSpace();
space.id = 'space-1';
space.name = 'Test Space';
space.spaceType = 'chat';
space.owner = user;
// This should not throw
await expect(adapter.save(space)).resolves.not.toThrow();
});
it('should handle ManyToMany relationships with function targets', async () => {
// Register entities
registry.registerEntity(TestUser);
registry.registerEntity(TestSpace);
// Create a user
const user = new TestUser();
user.id = 'user-1';
user.name = 'Test User';
user.email = 'test@example.com';
// Create a space with the user as participant
const space = new TestSpace();
space.id = 'space-1';
space.name = 'Test Space';
space.spaceType = 'chat';
space.participants = [user];
// This should not throw
await expect(adapter.save(space)).resolves.not.toThrow();
});
it('should handle both ManyToOne and ManyToMany relationships together', async () => {
// Register entities
registry.registerEntity(TestUser);
registry.registerEntity(TestSpace);
// Create users
const owner = new TestUser();
owner.id = 'owner-1';
owner.name = 'Owner';
owner.email = 'owner@example.com';
const participant = new TestUser();
participant.id = 'participant-1';
participant.name = 'Participant';
participant.email = 'participant@example.com';
// Create a space with both owner and participants
const space = new TestSpace();
space.id = 'space-1';
space.name = 'Test Space';
space.spaceType = 'chat';
space.owner = owner;
space.participants = [owner, participant];
// This should not throw
await expect(adapter.save(space)).resolves.not.toThrow();
});
it('should get entity labels correctly for dynamic import targets', () => {
// Register entities
registry.registerEntity(TestUser);
registry.registerEntity(TestSpace);
// Test that we can get labels for the target types
const userLabels = (adapter as any).getEntityLabels(TestUser);
const spaceLabels = (adapter as any).getEntityLabels(TestSpace);
expect(userLabels).toEqual(['User']);
expect(spaceLabels).toEqual(['Space']);
});
});
describe('Promise Resolution', () => {
it('should handle Promise-based targets (simulating dynamic imports)', async () => {
// Register entities
registry.registerEntity(TestUser);
registry.registerEntity(TestSpace);
// Create a Promise-based target (this simulates what happens with dynamic imports)
const promiseTarget = Promise.resolve(TestUser);
// Test that getEntityLabels can handle Promise targets
const labels = await (adapter as any).getEntityLabels(promiseTarget);
expect(labels).toEqual(['User']);
});
it('should handle mixed Promise and non-Promise targets', async () => {
// Register entities
registry.registerEntity(TestUser);
registry.registerEntity(TestSpace);
// Test regular class
const regularLabels = (adapter as any).getEntityLabels(TestUser);
expect(regularLabels).toEqual(['User']);
// Test Promise-wrapped class
const promiseTarget = Promise.resolve(TestUser);
const promiseLabels = await (adapter as any).getEntityLabels(promiseTarget);
expect(promiseLabels).toEqual(['User']);
});
});
});