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(); } });