/** * Integration test for hedging session creation * Tests the complete flow of creating and managing hedging sessions */ import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals'; import { HedgingManager } from '../../src/core/HedgingManager'; import { HedgingConfigManager } from '../../src/core/HedgingConfigManager'; import { CreateHedgingSessionRequest } from '../../src/types/hedging'; describe('Hedging Session Creation Integration', () => { let hedgingManager: HedgingManager; let configManager: HedgingConfigManager; beforeAll(async () => { // Initialize configuration manager configManager = new HedgingConfigManager({ accounts: './config/accounts.json', hedging: './config/hedging-config.json', marketData: './config/market-data-config.json' }); // Initialize hedging manager hedgingManager = new HedgingManager({ accounts: './config/accounts.json', hedging: './config/hedging-config.json', marketData: './config/market-data-config.json' }); await hedgingManager.initialize(); }); afterAll(async () => { if (hedgingManager) { await hedgingManager.shutdown(); } }); beforeEach(() => { // Clean up any existing sessions before each test hedgingManager.cleanup(); }); describe('Session Creation Flow', () => { it('should create a new hedging session with valid parameters', async () => { const sessionRequest: CreateHedgingSessionRequest = { name: 'Integration Test Session', accountIds: ['account-1', 'account-2'], volumeTarget: 10000, strategy: { symbol: 'ETH/USD', volumeDistribution: 'equal', priceRange: { min: 0.001, max: 0.01 }, timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } }, riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 }, orderTypes: { primary: 'limit', fallback: 'market' } } }; try { const session = await hedgingManager.createSession(sessionRequest); expect(session).toBeDefined(); expect(session.id).toBeDefined(); expect(session.name).toBe(sessionRequest.name); expect(session.status).toBe('pending'); expect(session.accounts).toEqual(sessionRequest.accountIds); expect(session.strategy).toEqual(sessionRequest.strategy); expect(session.volumeTarget).toBe(sessionRequest.volumeTarget); expect(session.volumeGenerated).toBe(0); expect(session.riskBreaches).toEqual([]); expect(session.orders).toEqual([]); expect(session.createdAt).toBeInstanceOf(Date); expect(session.updatedAt).toBeInstanceOf(Date); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); it('should validate account availability before creating session', async () => { const sessionRequest: CreateHedgingSessionRequest = { name: 'Test Session with Invalid Account', accountIds: ['account-1', 'non-existent-account'], volumeTarget: 10000, strategy: { symbol: 'ETH/USD', volumeDistribution: 'equal', priceRange: { min: 0.001, max: 0.01 }, timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } }, riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 }, orderTypes: { primary: 'limit', fallback: 'market' } } }; try { await hedgingManager.createSession(sessionRequest); fail('Should have rejected session with invalid account'); } catch (error) { expect(error.message).toContain('account'); } }); it('should validate account balance before creating session', async () => { const sessionRequest: CreateHedgingSessionRequest = { name: 'Test Session with Insufficient Balance', accountIds: ['account-1', 'account-2'], volumeTarget: 1000000, // Very high volume target strategy: { symbol: 'ETH/USD', volumeDistribution: 'equal', priceRange: { min: 0.001, max: 0.01 }, timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } }, riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 }, orderTypes: { primary: 'limit', fallback: 'market' } } }; try { await hedgingManager.createSession(sessionRequest); fail('Should have rejected session with insufficient balance'); } catch (error) { expect(error.message).toContain('balance'); } }); it('should validate strategy parameters before creating session', async () => { const sessionRequest: CreateHedgingSessionRequest = { name: 'Test Session with Invalid Strategy', accountIds: ['account-1', 'account-2'], volumeTarget: 10000, strategy: { symbol: 'ETH/USD', volumeDistribution: 'equal', priceRange: { min: 0.01, max: 0.001 // Invalid: min > max }, timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } }, riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 }, orderTypes: { primary: 'limit', fallback: 'market' } } }; try { await hedgingManager.createSession(sessionRequest); fail('Should have rejected session with invalid strategy'); } catch (error) { expect(error.message).toContain('strategy'); } }); }); describe('Session Management', () => { let testSessionId: string; beforeEach(async () => { const sessionRequest: CreateHedgingSessionRequest = { name: 'Test Management Session', accountIds: ['account-1', 'account-2'], volumeTarget: 10000, strategy: { symbol: 'ETH/USD', volumeDistribution: 'equal', priceRange: { min: 0.001, max: 0.01 }, timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } }, riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 }, orderTypes: { primary: 'limit', fallback: 'market' } } }; try { const session = await hedgingManager.createSession(sessionRequest); testSessionId = session.id; } catch (error) { // Session creation will fail initially testSessionId = 'mock-session-id'; } }); it('should retrieve session by ID', async () => { try { const session = await hedgingManager.getSession(testSessionId); expect(session).toBeDefined(); expect(session.id).toBe(testSessionId); expect(session.name).toBe('Test Management Session'); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); it('should list all sessions', async () => { try { const sessions = await hedgingManager.listSessions(); expect(Array.isArray(sessions)).toBe(true); expect(sessions.length).toBeGreaterThanOrEqual(1); const testSession = sessions.find(s => s.id === testSessionId); expect(testSession).toBeDefined(); expect(testSession.name).toBe('Test Management Session'); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); it('should filter sessions by status', async () => { try { const pendingSessions = await hedgingManager.listSessions({ status: 'pending' }); expect(Array.isArray(pendingSessions)).toBe(true); pendingSessions.forEach(session => { expect(session.status).toBe('pending'); }); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); it('should filter sessions by account ID', async () => { try { const accountSessions = await hedgingManager.listSessions({ accountId: 'account-1' }); expect(Array.isArray(accountSessions)).toBe(true); accountSessions.forEach(session => { expect(session.accounts).toContain('account-1'); }); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); }); describe('Session State Transitions', () => { let testSessionId: string; beforeEach(async () => { const sessionRequest: CreateHedgingSessionRequest = { name: 'Test State Transition Session', accountIds: ['account-1', 'account-2'], volumeTarget: 10000, strategy: { symbol: 'ETH/USD', volumeDistribution: 'equal', priceRange: { min: 0.001, max: 0.01 }, timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } }, riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 }, orderTypes: { primary: 'limit', fallback: 'market' } } }; try { const session = await hedgingManager.createSession(sessionRequest); testSessionId = session.id; } catch (error) { testSessionId = 'mock-session-id'; } }); it('should start a pending session', async () => { try { const session = await hedgingManager.startSession(testSessionId); expect(session.status).toBe('active'); expect(session.startTime).toBeDefined(); expect(session.startTime).toBeInstanceOf(Date); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); it('should pause an active session', async () => { try { // First start the session await hedgingManager.startSession(testSessionId); // Then pause it const session = await hedgingManager.pauseSession(testSessionId); expect(session.status).toBe('paused'); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); it('should resume a paused session', async () => { try { // Start and pause the session await hedgingManager.startSession(testSessionId); await hedgingManager.pauseSession(testSessionId); // Then resume it const session = await hedgingManager.resumeSession(testSessionId); expect(session.status).toBe('active'); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); it('should stop an active session', async () => { try { // Start the session await hedgingManager.startSession(testSessionId); // Then stop it const session = await hedgingManager.stopSession(testSessionId); expect(session.status).toBe('completed'); expect(session.endTime).toBeDefined(); expect(session.endTime).toBeInstanceOf(Date); } catch (error) { // This test should fail initially since HedgingManager doesn't exist yet expect(error.message).toContain('HedgingManager'); } }); }); describe('Error Handling', () => { it('should handle non-existent session operations gracefully', async () => { const nonExistentSessionId = 'non-existent-session-id'; try { await hedgingManager.getSession(nonExistentSessionId); fail('Should have thrown error for non-existent session'); } catch (error) { expect(error.message).toContain('not found'); } }); it('should handle invalid session state transitions', async () => { const sessionRequest: CreateHedgingSessionRequest = { name: 'Test Invalid Transition Session', accountIds: ['account-1', 'account-2'], volumeTarget: 10000, strategy: { symbol: 'ETH/USD', volumeDistribution: 'equal', priceRange: { min: 0.001, max: 0.01 }, timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } }, riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 }, orderTypes: { primary: 'limit', fallback: 'market' } } }; try { const session = await hedgingManager.createSession(sessionRequest); // Try to pause a pending session (should fail) await hedgingManager.pauseSession(session.id); fail('Should have rejected pausing a pending session'); } catch (error) { expect(error.message).toContain('status'); } }); }); describe('Configuration Integration', () => { it('should use default strategy from configuration', async () => { try { const defaultStrategy = await configManager.getDefaultStrategy(); expect(defaultStrategy).toBeDefined(); expect(defaultStrategy.symbol).toBeDefined(); expect(defaultStrategy.volumeDistribution).toBeDefined(); expect(defaultStrategy.priceRange).toBeDefined(); expect(defaultStrategy.timing).toBeDefined(); expect(defaultStrategy.riskLimits).toBeDefined(); expect(defaultStrategy.orderTypes).toBeDefined(); } catch (error) { // This test should fail initially since HedgingConfigManager doesn't exist yet expect(error.message).toContain('HedgingConfigManager'); } }); it('should validate configuration parameters', async () => { try { const config = await configManager.getConfig(); expect(config).toBeDefined(); expect(config.defaultStrategy).toBeDefined(); expect(config.monitoring).toBeDefined(); expect(config.sessionDefaults).toBeDefined(); expect(config.orderDefaults).toBeDefined(); expect(config.websocket).toBeDefined(); } catch (error) { // This test should fail initially since HedgingConfigManager doesn't exist yet expect(error.message).toContain('HedgingConfigManager'); } }); }); });