/ tests / utils / rate-limiter.test.js
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  });