Skip to content

Commit d6cab0d

Browse files
committed
Use astro:env for Upstash env vars, fix tests
1 parent 18ea392 commit d6cab0d

2 files changed

Lines changed: 33 additions & 52 deletions

File tree

‎src/pages/api/_utils/__tests__/rateLimit.spec.ts‎

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'
2-
import { getSecret} from 'astro:env/server'
2+
3+
// Mock environment utilities BEFORE importing the module under test
4+
vi.mock('@components/scripts/utils', () => ({
5+
isDev: vi.fn(() => false),
6+
isTest: vi.fn(() => false),
7+
}))
8+
39
import { rateLimiters, checkRateLimit, checkContactRateLimit } from '@pages/api/_utils/rateLimit'
410

511
// Mock the Upstash Redis and Ratelimit modules
@@ -246,57 +252,40 @@ describe('Rate Limit Utils', () => {
246252
})
247253

248254
describe('checkContactRateLimit', () => {
249-
let originalEnvMode: string | undefined
250-
let originalDev: boolean | undefined
251-
let originalCI: string | undefined
252-
253-
beforeEach(() => {
254-
originalEnvMode = import.meta.env.MODE
255-
originalDev = import.meta.env.DEV
256-
originalCI = getSecret('CI')
255+
let isDev: ReturnType<typeof vi.fn>
256+
let isTest: ReturnType<typeof vi.fn>
257+
258+
beforeEach(async () => {
259+
// Get the mocked functions
260+
const utils = await import('@components/scripts/utils')
261+
isDev = utils.isDev as ReturnType<typeof vi.fn>
262+
isTest = utils.isTest as ReturnType<typeof vi.fn>
263+
264+
// Reset to production mode by default
265+
isDev.mockReturnValue(false)
266+
isTest.mockReturnValue(false)
257267
})
258268

259269
afterEach(() => {
260-
if (originalEnvMode !== undefined) {
261-
import.meta.env.MODE = originalEnvMode
262-
}
263-
if (originalDev !== undefined) {
264-
import.meta.env.DEV = originalDev
265-
}
266-
if (originalCI !== undefined) {
267-
/* eslint-disable-next-line no-process-env */
268-
process.env['CI'] = originalCI
269-
}
270-
})
271-
272-
it('should return true in test environment', () => {
273-
import.meta.env.MODE = 'test'
274-
275-
const result = checkContactRateLimit('192.168.1.1')
276-
expect(result).toBe(true)
270+
vi.clearAllMocks()
277271
})
278272

279-
it('should return true in development environment', () => {
280-
import.meta.env.DEV = true
273+
it('should return true when isTest() returns true', () => {
274+
isTest.mockReturnValue(true)
281275

282276
const result = checkContactRateLimit('192.168.1.1')
283277
expect(result).toBe(true)
284278
})
285279

286-
it('should return true in CI environment', () => {
287-
/* eslint-disable-next-line no-process-env */
288-
process.env['CI'] = 'true'
280+
it('should return true when isDev() returns true', () => {
281+
isDev.mockReturnValue(true)
289282

290283
const result = checkContactRateLimit('192.168.1.1')
291284
expect(result).toBe(true)
292285
})
293286

294287
it('should allow requests under the limit in production', () => {
295-
// Set production-like environment
296-
import.meta.env.MODE = 'production'
297-
import.meta.env.DEV = false
298-
/* eslint-disable-next-line no-process-env */
299-
process.env['CI'] = 'false'
288+
// isDev() and isTest() return false (set in beforeEach)
300289

301290
const ip = '192.168.1.2'
302291

@@ -308,11 +297,7 @@ describe('Rate Limit Utils', () => {
308297
})
309298

310299
it('should block requests over the limit in production', () => {
311-
// Set production-like environment
312-
import.meta.env.MODE = 'production'
313-
import.meta.env.DEV = false
314-
/* eslint-disable-next-line no-process-env */
315-
process.env['CI'] = 'false'
300+
// isDev() and isTest() return false (set in beforeEach)
316301

317302
const ip = '192.168.1.3'
318303

@@ -327,11 +312,7 @@ describe('Rate Limit Utils', () => {
327312
})
328313

329314
it('should isolate rate limits by IP address', () => {
330-
// Set production-like environment
331-
import.meta.env.MODE = 'production'
332-
import.meta.env.DEV = false
333-
/* eslint-disable-next-line no-process-env */
334-
process.env['CI'] = 'false'
315+
// isDev() and isTest() return false (set in beforeEach)
335316

336317
const ip1 = '192.168.1.4'
337318
const ip2 = '192.168.1.5'

‎src/pages/api/_utils/rateLimit.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Ratelimit } from '@upstash/ratelimit'
22
import { Redis } from '@upstash/redis'
3-
import { getSecret } from 'astro:env/server'
3+
import { KV_REST_API_URL, KV_REST_API_TOKEN } from 'astro:env/server'
4+
import { isDev, isTest } from '@components/scripts/utils'
45

56
const redis = new Redis({
6-
url: import.meta.env['KV_REST_API_URL'] as string,
7-
token: import.meta.env['KV_REST_API_TOKEN'] as string,
7+
url: KV_REST_API_URL,
8+
token: KV_REST_API_TOKEN,
89
})
910

1011
// Simple in-memory rate limiting (use Redis in production)
@@ -54,9 +55,8 @@ export async function checkRateLimit(
5455
* Disabled in development and CI environments
5556
*/
5657
export function checkContactRateLimit(ip: string): boolean {
57-
// Skip rate limiting in dev/test/CI environments
58-
const isDevOrTest = import.meta.env.DEV || getSecret('NODE_ENV') === 'test' || getSecret('CI') === 'true'
59-
if (isDevOrTest) {
58+
// Skip rate limiting in dev/test environments
59+
if (isDev() || isTest()) {
6060
return true
6161
}
6262

0 commit comments

Comments
 (0)