Skip to main content
Glama
GetRelationshipsUseCase.test.js12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const GetRelationshipsUseCase_1 = require("./GetRelationshipsUseCase"); const RelationshipAnalyzer_1 = require("../../domain/services/RelationshipAnalyzer"); const DatabaseConfig_1 = require("../../infrastructure/config/DatabaseConfig"); const Environment_1 = require("../../domain/value-objects/Environment"); const DatabaseSchema_1 = require("../../domain/entities/DatabaseSchema"); const TableInfo_1 = require("../../domain/entities/TableInfo"); const Column_1 = require("../../domain/entities/Column"); const ForeignKey_1 = require("../../domain/entities/ForeignKey"); (0, vitest_1.describe)('GetRelationshipsUseCase', () => { let useCase; let mockRepository; let mockCache; let relationshipAnalyzer; let mockDatabaseConfig; (0, vitest_1.beforeEach)(() => { // Mock repository mockRepository = { fetchDatabaseSchema: vitest_1.vi.fn(), fetchTableDetails: vitest_1.vi.fn(), fetchIndexInformation: vitest_1.vi.fn(), executeSQLQuery: vitest_1.vi.fn(), }; // Mock cache mockCache = { get: vitest_1.vi.fn(), set: vitest_1.vi.fn(), delete: vitest_1.vi.fn(), clear: vitest_1.vi.fn(), has: vitest_1.vi.fn(), }; // Real relationship analyzer relationshipAnalyzer = new RelationshipAnalyzer_1.RelationshipAnalyzer(); // Mock database config const databases = new Map(); databases.set(Environment_1.Environment.DEVELOPMENT, { name: 'dev_db', id: 'dev-123' }); databases.set(Environment_1.Environment.PRODUCTION, { name: 'prod_db', id: 'prod-789' }); mockDatabaseConfig = new DatabaseConfig_1.DatabaseConfig(databases); useCase = new GetRelationshipsUseCase_1.GetRelationshipsUseCase(mockRepository, relationshipAnalyzer, mockDatabaseConfig, mockCache); vitest_1.vi.clearAllMocks(); }); (0, vitest_1.describe)('constructor', () => { (0, vitest_1.it)('should create use case and freeze instance', () => { (0, vitest_1.expect)(Object.isFrozen(useCase)).toBe(true); }); }); (0, vitest_1.describe)('execute()', () => { (0, vitest_1.it)('should extract all relationships from schema', async () => { // Mock cache miss mockCache.get.mockResolvedValue(undefined); // Create schema with relationships const usersColumns = [new Column_1.Column('id', 'INTEGER', false, true, null)]; const ordersColumns = [ new Column_1.Column('id', 'INTEGER', false, true, null), new Column_1.Column('user_id', 'INTEGER', false, false, null), ]; const ordersForeignKeys = [new ForeignKey_1.ForeignKey('orders', 'user_id', 'users', 'id', 'CASCADE', 'RESTRICT')]; const usersTable = new TableInfo_1.TableInfo('users', 'table', usersColumns, [], []); const ordersTable = new TableInfo_1.TableInfo('orders', 'table', ordersColumns, [], ordersForeignKeys); const schema = new DatabaseSchema_1.DatabaseSchema('dev_db', Environment_1.Environment.DEVELOPMENT, [usersTable, ordersTable], new Date()); mockRepository.fetchDatabaseSchema.mockResolvedValue(schema); // Execute const result = await useCase.execute({ environment: Environment_1.Environment.DEVELOPMENT, }); // Verify repository was called (0, vitest_1.expect)(mockRepository.fetchDatabaseSchema).toHaveBeenCalledWith('dev-123'); // Verify cache was set (0, vitest_1.expect)(mockCache.set).toHaveBeenCalledWith('schema:development', schema, 600); // Verify response (0, vitest_1.expect)(result.databaseName).toBe('dev_db'); (0, vitest_1.expect)(result.environment).toBe(Environment_1.Environment.DEVELOPMENT); (0, vitest_1.expect)(result.relationshipCount).toBe(1); (0, vitest_1.expect)(result.relationships).toHaveLength(1); // Verify relationship details const rel = result.relationships[0]; (0, vitest_1.expect)(rel.fromTable).toBe('orders'); (0, vitest_1.expect)(rel.fromColumn).toBe('user_id'); (0, vitest_1.expect)(rel.toTable).toBe('users'); (0, vitest_1.expect)(rel.toColumn).toBe('id'); (0, vitest_1.expect)(rel.onDelete).toBe('CASCADE'); (0, vitest_1.expect)(rel.onUpdate).toBe('RESTRICT'); (0, vitest_1.expect)(rel.isRequired).toBe(true); }); (0, vitest_1.it)('should return cached schema when available', async () => { // Create and cache schema const table = new TableInfo_1.TableInfo('products', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], []); const cachedSchema = new DatabaseSchema_1.DatabaseSchema('dev_db', Environment_1.Environment.DEVELOPMENT, [table], new Date()); mockCache.get.mockResolvedValue(cachedSchema); // Execute await useCase.execute({ environment: Environment_1.Environment.DEVELOPMENT, }); // Verify cache was checked (0, vitest_1.expect)(mockCache.get).toHaveBeenCalledWith('schema:development'); // Verify repository was NOT called (0, vitest_1.expect)(mockRepository.fetchDatabaseSchema).not.toHaveBeenCalled(); // Verify cache was NOT set again (0, vitest_1.expect)(mockCache.set).not.toHaveBeenCalled(); }); (0, vitest_1.it)('should filter relationships by table name when specified', async () => { mockCache.get.mockResolvedValue(undefined); // Create schema with multiple relationships const usersTable = new TableInfo_1.TableInfo('users', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], []); const ordersTable = new TableInfo_1.TableInfo('orders', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], [new ForeignKey_1.ForeignKey('orders', 'user_id', 'users', 'id', 'CASCADE', null)]); const paymentsTable = new TableInfo_1.TableInfo('payments', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], [new ForeignKey_1.ForeignKey('payments', 'order_id', 'orders', 'id', 'RESTRICT', null)]); const schema = new DatabaseSchema_1.DatabaseSchema('dev_db', Environment_1.Environment.DEVELOPMENT, [usersTable, ordersTable, paymentsTable], new Date()); mockRepository.fetchDatabaseSchema.mockResolvedValue(schema); // Execute with table filter const result = await useCase.execute({ environment: Environment_1.Environment.DEVELOPMENT, tableName: 'orders', }); // Should return relationships where orders is either fromTable or toTable (0, vitest_1.expect)(result.relationshipCount).toBe(2); const fromOrders = result.relationships.find((r) => r.fromTable === 'orders'); const toOrders = result.relationships.find((r) => r.toTable === 'orders'); (0, vitest_1.expect)(fromOrders).toBeDefined(); (0, vitest_1.expect)(fromOrders?.toTable).toBe('users'); (0, vitest_1.expect)(toOrders).toBeDefined(); (0, vitest_1.expect)(toOrders?.fromTable).toBe('payments'); }); (0, vitest_1.it)('should handle schema with no relationships', async () => { mockCache.get.mockResolvedValue(undefined); // Create schema without foreign keys const table = new TableInfo_1.TableInfo('standalone', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], []); const schema = new DatabaseSchema_1.DatabaseSchema('dev_db', Environment_1.Environment.DEVELOPMENT, [table], new Date()); mockRepository.fetchDatabaseSchema.mockResolvedValue(schema); const result = await useCase.execute({ environment: Environment_1.Environment.DEVELOPMENT, }); (0, vitest_1.expect)(result.relationshipCount).toBe(0); (0, vitest_1.expect)(result.relationships).toHaveLength(0); }); (0, vitest_1.it)('should handle different environments correctly', async () => { mockCache.get.mockResolvedValue(undefined); const table = new TableInfo_1.TableInfo('items', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], []); const schema = new DatabaseSchema_1.DatabaseSchema('prod_db', Environment_1.Environment.PRODUCTION, [table], new Date()); mockRepository.fetchDatabaseSchema.mockResolvedValue(schema); const result = await useCase.execute({ environment: Environment_1.Environment.PRODUCTION, }); // Verify correct database ID used (0, vitest_1.expect)(mockRepository.fetchDatabaseSchema).toHaveBeenCalledWith('prod-789'); // Verify correct cache key (0, vitest_1.expect)(mockCache.set).toHaveBeenCalledWith('schema:production', schema, 600); // Verify response environment (0, vitest_1.expect)(result.environment).toBe(Environment_1.Environment.PRODUCTION); (0, vitest_1.expect)(result.databaseName).toBe('prod_db'); }); (0, vitest_1.it)('should correctly identify required relationships', async () => { mockCache.get.mockResolvedValue(undefined); const table1 = new TableInfo_1.TableInfo('table1', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], []); const table2 = new TableInfo_1.TableInfo('table2', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], [ new ForeignKey_1.ForeignKey('table2', 'fk1', 'table1', 'id', 'CASCADE', null), // Required (CASCADE) new ForeignKey_1.ForeignKey('table2', 'fk2', 'table1', 'id', 'SET NULL', null), // Not required ]); const schema = new DatabaseSchema_1.DatabaseSchema('dev_db', Environment_1.Environment.DEVELOPMENT, [table1, table2], new Date()); mockRepository.fetchDatabaseSchema.mockResolvedValue(schema); const result = await useCase.execute({ environment: Environment_1.Environment.DEVELOPMENT, }); (0, vitest_1.expect)(result.relationshipCount).toBe(2); const cascadeRel = result.relationships.find((r) => r.onDelete === 'CASCADE'); const setNullRel = result.relationships.find((r) => r.onDelete === 'SET NULL'); (0, vitest_1.expect)(cascadeRel?.isRequired).toBe(true); (0, vitest_1.expect)(setNullRel?.isRequired).toBe(false); }); (0, vitest_1.it)('should return empty array when filtering by non-existent table', async () => { mockCache.get.mockResolvedValue(undefined); const table = new TableInfo_1.TableInfo('users', 'table', [new Column_1.Column('id', 'INTEGER', false, true, null)], [], [new ForeignKey_1.ForeignKey('users', 'dept_id', 'departments', 'id', null, null)]); const schema = new DatabaseSchema_1.DatabaseSchema('dev_db', Environment_1.Environment.DEVELOPMENT, [table], new Date()); mockRepository.fetchDatabaseSchema.mockResolvedValue(schema); const result = await useCase.execute({ environment: Environment_1.Environment.DEVELOPMENT, tableName: 'nonexistent', }); (0, vitest_1.expect)(result.relationshipCount).toBe(0); (0, vitest_1.expect)(result.relationships).toHaveLength(0); }); }); }); //# sourceMappingURL=GetRelationshipsUseCase.test.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/semanticintent/semantic-d1-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server