Files
vngeoguessr/tests/debug-access.test.js
tiennm99 35999a809d fix(api): give every store call a deadline, harden the small things
Every Upstash command and Neon query now has a deadline (5 s and 8 s): the
Redis client retried a hung connection past the browser's fifteen-second
wait, and the Neon client had no limit. Usernames are NFC-normalised so a
tone mark typed as a combining character is accepted and does not make two
board members of one name. The debug key is compared in constant time. A
panorama whose district the tree does not know fails the draw before a
session is written, not /api/guess after it is consumed. The country branch
of countPanos and the never-triggered per-city cap are gone.
2026-09-29 20:13:07 +07:00

59 lines
2.4 KiB
JavaScript

import { describe, it, expect, afterEach } from 'vitest';
import { debugAccessAllowed } from '../src/lib/debug-access.js';
// The debug routes return panorama coordinates. Open anywhere but Vercel
// production, where they answer only a caller holding the configured key.
const ORIGINAL = { env: process.env.VERCEL_ENV, key: process.env.DEBUG_ACCESS_KEY };
function request(headers = {}) {
return new Request('http://localhost/api/debug/pano?id=1', { headers });
}
afterEach(() => {
process.env.VERCEL_ENV = ORIGINAL.env;
process.env.DEBUG_ACCESS_KEY = ORIGINAL.key;
if (ORIGINAL.env === undefined) delete process.env.VERCEL_ENV;
if (ORIGINAL.key === undefined) delete process.env.DEBUG_ACCESS_KEY;
});
describe('debugAccessAllowed', () => {
it('is open off production, including preview deployments', () => {
delete process.env.VERCEL_ENV;
expect(debugAccessAllowed(request())).toBe(true);
process.env.VERCEL_ENV = 'preview';
expect(debugAccessAllowed(request())).toBe(true);
});
it('treats a production build with no Vercel environment as production', () => {
delete process.env.VERCEL_ENV;
const original = process.env.NODE_ENV;
process.env.NODE_ENV = 'production';
try {
delete process.env.DEBUG_ACCESS_KEY;
expect(debugAccessAllowed(request())).toBe(false);
} finally {
// Assigning undefined would store the string "undefined".
if (original === undefined) delete process.env.NODE_ENV;
else process.env.NODE_ENV = original;
}
});
it('is closed in production with no key configured', () => {
process.env.VERCEL_ENV = 'production';
delete process.env.DEBUG_ACCESS_KEY;
expect(debugAccessAllowed(request({ 'x-debug-key': 'anything' }))).toBe(false);
});
it('opens in production to the header or the cookie carrying the key', () => {
process.env.VERCEL_ENV = 'production';
process.env.DEBUG_ACCESS_KEY = 'secret-key';
expect(debugAccessAllowed(request())).toBe(false);
expect(debugAccessAllowed(request({ 'x-debug-key': 'wrong' }))).toBe(false);
expect(debugAccessAllowed(request({ 'x-debug-key': 'secret-ke' }))).toBe(false);
expect(debugAccessAllowed(request({ 'x-debug-key': 'secret-key-and-more' }))).toBe(false);
expect(debugAccessAllowed(request({ 'x-debug-key': 'secret-key' }))).toBe(true);
expect(debugAccessAllowed(request({ cookie: 'theme=dark; vng_debug=secret-key' }))).toBe(true);
});
});