Files
pokemon-inventory/apps/api/tests/integration/redis-login-rate-limiter.test.js
T
fragginwagon c728016dec feat: establish auth listing and image vertical slices
Includes MFA-capable authentication, session and CSRF security, password recovery, listing lifecycle and ownership rules, inventory image metadata, local ImageStorage, migrations, tests, and implementation status documentation. Verification: npm test (62 passing) and integration suite (14 passing).
2026-09-08 17:32:03 -04:00

41 lines
1.4 KiB
JavaScript

import assert from 'node:assert/strict';
import { randomUUID } from 'node:crypto';
import test from 'node:test';
import { createRedisConnection } from '../../src/infrastructure/redis/client.js';
import { createRedisLoginRateLimiter } from '../../src/modules/auth/services/login-rate-limiter.js';
const redisUrl = process.env.TEST_REDIS_URL;
if (!redisUrl) {
throw new Error('TEST_REDIS_URL is required to run integration tests.');
}
test('shares login attempts across limiter instances', async () => {
const redis = await createRedisConnection(redisUrl);
const keyPrefix = `pokemon-inventory:test:auth:${randomUUID()}:`;
try {
const firstLimiter = createRedisLoginRateLimiter({
keyPrefix,
maxAttempts: 2,
redisClient: redis.client,
});
const secondLimiter = createRedisLoginRateLimiter({
keyPrefix,
maxAttempts: 2,
redisClient: redis.client,
});
assert.deepEqual(await firstLimiter.consume('198.51.100.8'), { allowed: true });
assert.deepEqual(await secondLimiter.consume('198.51.100.8'), { allowed: true });
const blockedAttempt = await firstLimiter.consume('198.51.100.8');
assert.equal(blockedAttempt.allowed, false);
assert.ok(blockedAttempt.retryAfterSeconds > 0);
assert.deepEqual(await secondLimiter.consume('198.51.100.9'), { allowed: true });
} finally {
await redis.close();
}
});