From 83bd87d12941c6c17a32bc7fb63b2d8cea2faaa8 Mon Sep 17 00:00:00 2001 From: Jonas Daniels Date: Fri, 11 Apr 2025 22:38:01 +0200 Subject: [PATCH] Fix incrBy to incrby in rate limit implementation --- .changeset/giant-humans-say.md | 5 +++++ .../service-utils/src/core/rateLimit/index.ts | 4 ++-- .../src/core/rateLimit/rateLimit.test.ts | 20 +++++++++---------- 3 files changed, 17 insertions(+), 12 deletions(-) create mode 100644 .changeset/giant-humans-say.md diff --git a/.changeset/giant-humans-say.md b/.changeset/giant-humans-say.md new file mode 100644 index 00000000000..49905870316 --- /dev/null +++ b/.changeset/giant-humans-say.md @@ -0,0 +1,5 @@ +--- +"@thirdweb-dev/service-utils": patch +--- + +fix incrby diff --git a/packages/service-utils/src/core/rateLimit/index.ts b/packages/service-utils/src/core/rateLimit/index.ts index 578e37ca35c..e52cfc7a86b 100644 --- a/packages/service-utils/src/core/rateLimit/index.ts +++ b/packages/service-utils/src/core/rateLimit/index.ts @@ -7,7 +7,7 @@ const RATE_LIMIT_WINDOW_SECONDS = 10; type IRedis = { get: (key: string) => Promise; expire(key: string, seconds: number): Promise; - incrBy(key: string, value: number): Promise; + incrby(key: string, value: number): Promise; }; export async function rateLimit(args: { @@ -83,7 +83,7 @@ export async function rateLimit(args: { // do not await this, it just needs to execute at all (async () => // always incrementBy the amount specified for the key - await redis.incrBy(key, increment).then(async () => { + await redis.incrby(key, increment).then(async () => { // if the initial request count was 0, set the key to expire in the future if (requestCount === 0) { await redis.expire(key, RATE_LIMIT_WINDOW_SECONDS); diff --git a/packages/service-utils/src/core/rateLimit/rateLimit.test.ts b/packages/service-utils/src/core/rateLimit/rateLimit.test.ts index 1b2153dcf90..f4f324831b1 100644 --- a/packages/service-utils/src/core/rateLimit/rateLimit.test.ts +++ b/packages/service-utils/src/core/rateLimit/rateLimit.test.ts @@ -5,7 +5,7 @@ import { rateLimit } from "./index.js"; const mockRedis = { get: vi.fn(), expire: vi.fn(), - incrBy: vi.fn(), + incrby: vi.fn(), }; describe("rateLimit", () => { @@ -14,7 +14,7 @@ describe("rateLimit", () => { vi.clearAllMocks(); mockRedis.get.mockReset(); mockRedis.expire.mockReset(); - mockRedis.incrBy.mockReset(); + mockRedis.incrby.mockReset(); }); afterEach(() => { @@ -52,7 +52,7 @@ describe("rateLimit", () => { rateLimit: 50, }); - expect(mockRedis.incrBy).toHaveBeenCalledTimes(1); + expect(mockRedis.incrby).toHaveBeenCalledTimes(1); }); it("should rate limit if exceeded hard limit", async () => { @@ -74,7 +74,7 @@ describe("rateLimit", () => { errorCode: "RATE_LIMIT_EXCEEDED", }); - expect(mockRedis.incrBy).not.toHaveBeenCalled(); + expect(mockRedis.incrby).not.toHaveBeenCalled(); }); it("expires on the first incr request only", async () => { @@ -92,7 +92,7 @@ describe("rateLimit", () => { requestCount: 2, rateLimit: 50, }); - expect(mockRedis.incrBy).toHaveBeenCalled(); + expect(mockRedis.incrby).toHaveBeenCalled(); }); it("enforces rate limit if sampled (hit)", async () => { @@ -169,7 +169,7 @@ describe("rateLimit", () => { requestCount: 1, rateLimit: 50, }); - expect(mockRedis.incrBy).toHaveBeenCalledWith(expect.any(String), 1); + expect(mockRedis.incrby).toHaveBeenCalledWith(expect.any(String), 1); }); it("should handle null response from redis", async () => { @@ -216,7 +216,7 @@ describe("rateLimit", () => { mockRedis.get.mockResolvedValue("0"); // Mock redis.set to have 100ms delay - mockRedis.incrBy.mockImplementation( + mockRedis.incrby.mockImplementation( () => new Promise((resolve) => { setTimeout(() => resolve(1), 100); @@ -256,13 +256,13 @@ describe("rateLimit", () => { } // Redis set should be called 3 times - expect(mockRedis.incrBy).toHaveBeenCalledTimes(3); + expect(mockRedis.incrby).toHaveBeenCalledTimes(3); }); it("should handle custom increment values", async () => { // Mock initial state mockRedis.get.mockResolvedValue("5"); - mockRedis.incrBy.mockResolvedValue(10); + mockRedis.incrby.mockResolvedValue(10); const result = await rateLimit({ team: validTeamResponse, @@ -279,7 +279,7 @@ describe("rateLimit", () => { }); // Verify redis was called with correct increment - expect(mockRedis.incrBy).toHaveBeenCalledWith( + expect(mockRedis.incrby).toHaveBeenCalledWith( expect.stringContaining("rate-limit"), 5, );