#!/usr/bin/env bun import { getLogger } from '@stock-bot/logger'; const logger = getLogger('test-advanced-rate-limit'); async function testAdvancedRateLimits() { logger.info('Testing advanced rate limit features...'); const baseUrl = 'http://localhost:3001/api'; logger.info('\nšŸ“‹ Rate Limit Configuration:'); logger.info('Handler limits: 100pts/sec, 10k pts/hour, 100k pts/day'); logger.info('fetch-daily-prices: 1 point per call'); logger.info('fetch-fundamentals: 10 points per call'); logger.info('fetch-news: 50 points per call (custom limits: 10pts/min, 100pts/hour)'); // First test: test-burst operation logger.info('\nšŸš€ Testing burst operation with mixed costs...'); const burstResponse = await fetch(`${baseUrl}/handlers/eod/operations/test-burst`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ operationsToTest: ['fetch-daily-prices', 'fetch-fundamentals', 'fetch-news'], burstSize: 30 }) }); const burstResult = await burstResponse.json(); logger.info('Burst test result:', burstResult); // Wait for jobs to process logger.info('\nā³ Waiting 10 seconds for jobs to process...'); await new Promise(resolve => setTimeout(resolve, 10000)); // Test individual operations with different costs logger.info('\nšŸ“Š Testing individual operations:'); // Test cheap operation (1 point) logger.info('\n1ļøāƒ£ Testing fetch-daily-prices (1 point each)...'); for (let i = 0; i < 5; i++) { const response = await fetch(`${baseUrl}/handlers/eod/operations/fetch-daily-prices`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ test: true, index: i }) }); logger.info(`Request ${i + 1}: ${response.status} ${response.statusText}`); } // Test medium cost operation (10 points) logger.info('\nšŸ”Ÿ Testing fetch-fundamentals (10 points each)...'); for (let i = 0; i < 3; i++) { const response = await fetch(`${baseUrl}/handlers/eod/operations/fetch-fundamentals`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ test: true, index: i }) }); logger.info(`Request ${i + 1}: ${response.status} ${response.statusText}`); } // Test expensive operation (50 points) logger.info('\nšŸ’° Testing fetch-news (50 points each, custom limits)...'); for (let i = 0; i < 2; i++) { const response = await fetch(`${baseUrl}/handlers/eod/operations/fetch-news`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ test: true, index: i }) }); logger.info(`Request ${i + 1}: ${response.status} ${response.statusText}`); } logger.info('\nāœ… Test completed!'); logger.info('Check the data-ingestion service logs to see rate limiting in action.'); } // Health check before running tests async function checkService() { try { const response = await fetch('http://localhost:3001/health'); if (!response.ok) { throw new Error('Service not healthy'); } return true; } catch (error) { logger.error('Data ingestion service not running. Start it with: bun run dev'); return false; } } async function main() { if (await checkService()) { await testAdvancedRateLimits(); } } main().catch(error => { logger.error('Test failed:', error); process.exit(1); });