rate-limiter.test.js
1 import { test } from 'node:test'; 2 import assert from 'node:assert'; 3 import { 4 openRouterLimiter, 5 twilioLimiter, 6 zenrowsLimiter, 7 resendLimiter, 8 dataForSEOLimiter, 9 } from '../../src/utils/rate-limiter.js'; 10 11 test('Rate Limiter - OpenRouter limiter configuration', () => { 12 assert.ok(openRouterLimiter, 'OpenRouter limiter should be defined'); 13 assert.strictEqual(typeof openRouterLimiter.schedule, 'function', 'Should have schedule method'); 14 }); 15 16 test('Rate Limiter - Twilio limiter configuration', () => { 17 assert.ok(twilioLimiter, 'Twilio limiter should be defined'); 18 assert.strictEqual(typeof twilioLimiter.schedule, 'function', 'Should have schedule method'); 19 }); 20 21 test('Rate Limiter - ZenRows limiter configuration', () => { 22 assert.ok(zenrowsLimiter, 'ZenRows limiter should be defined'); 23 assert.strictEqual(typeof zenrowsLimiter.schedule, 'function', 'Should have schedule method'); 24 }); 25 26 test('Rate Limiter - Resend limiter configuration', () => { 27 assert.ok(resendLimiter, 'Resend limiter should be defined'); 28 assert.strictEqual(typeof resendLimiter.schedule, 'function', 'Should have schedule method'); 29 }); 30 31 test('Rate Limiter - DataForSEO limiter configuration', () => { 32 assert.ok(dataForSEOLimiter, 'DataForSEO limiter should be defined'); 33 assert.strictEqual(typeof dataForSEOLimiter.schedule, 'function', 'Should have schedule method'); 34 }); 35 36 test('Rate Limiter - OpenRouter respects minimum time between requests', async () => { 37 const startTime = Date.now(); 38 const results = []; 39 40 // Schedule 3 tasks 41 // Default minTime = 60000 / 194 ≈ 309ms → 3 tasks need 2 gaps = ~618ms minimum 42 const promises = [ 43 openRouterLimiter.schedule(() => Promise.resolve('task1')), 44 openRouterLimiter.schedule(() => Promise.resolve('task2')), 45 openRouterLimiter.schedule(() => Promise.resolve('task3')), 46 ]; 47 48 for (const promise of promises) { 49 results.push(await promise); 50 } 51 52 const elapsed = Date.now() - startTime; 53 54 // Should take at least 600ms (2 gaps × ~309ms at 194 RPM default) 55 assert.ok(elapsed >= 600, `Should take at least 600ms, took ${elapsed}ms`); 56 assert.deepStrictEqual(results, ['task1', 'task2', 'task3']); 57 }); 58 59 test('Rate Limiter - Twilio respects minimum time between requests', async () => { 60 const startTime = Date.now(); 61 const results = []; 62 63 // Schedule 2 tasks to keep the test fast while still verifying throttling. 64 // Default minTime = 1000 / 0.7 ≈ 1429ms → 2 tasks need 1 gap = ~1429ms minimum 65 const promises = [ 66 twilioLimiter.schedule(() => Promise.resolve('sms1')), 67 twilioLimiter.schedule(() => Promise.resolve('sms2')), 68 ]; 69 70 for (const promise of promises) { 71 results.push(await promise); 72 } 73 74 const elapsed = Date.now() - startTime; 75 76 // Should take at least 1400ms (1 gap × ~1429ms at 0.7 SMS/sec default) 77 assert.ok(elapsed >= 1400, `Should take at least 1400ms, took ${elapsed}ms`); 78 assert.deepStrictEqual(results, ['sms1', 'sms2']); 79 }); 80 81 test('Rate Limiter - Handles errors in scheduled tasks', async () => { 82 const error = new Error('Task failed'); 83 84 await assert.rejects( 85 async () => { 86 await openRouterLimiter.schedule(() => Promise.reject(error)); 87 }, 88 error, 89 'Should propagate errors from scheduled tasks' 90 ); 91 });