From 42217e182e200c372871ccc29f4ef7274b99ee5c Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Tue, 31 Mar 2026 00:24:28 -0700 Subject: [PATCH] test: add regression tests for ID validation with Prisma v7 --- src/__tests__/unit/id-validation.test.ts | 128 +++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/__tests__/unit/id-validation.test.ts diff --git a/src/__tests__/unit/id-validation.test.ts b/src/__tests__/unit/id-validation.test.ts new file mode 100644 index 0000000..d5b82c7 --- /dev/null +++ b/src/__tests__/unit/id-validation.test.ts @@ -0,0 +1,128 @@ +/** + * Unit Tests: ID Validation + * + * Tests for ID parsing and validation in API routes and pages + */ + +import { describe, test, expect } from 'vitest'; + +describe('ID Validation', () => { + describe('parseInt with validation', () => { + test('should parse valid numeric string', () => { + const id = '123'; + const parsedId = parseInt(id, 10); + + expect(parsedId).toBe(123); + expect(isNaN(parsedId)).toBe(false); + }); + + test('should return NaN for non-numeric string', () => { + const id = 'abc'; + const parsedId = parseInt(id, 10); + + expect(isNaN(parsedId)).toBe(true); + }); + + test('should return NaN for empty string', () => { + const id = ''; + const parsedId = parseInt(id, 10); + + expect(isNaN(parsedId)).toBe(true); + }); + + test('should return NaN for non-numeric strings', () => { + const id = 'abc'; + const parsedId = parseInt(id, 10); + + expect(isNaN(parsedId)).toBe(true); + }); + + test('should handle partial numeric strings (parseInt stops at first non-numeric)', () => { + const id = '123abc'; + const parsedId = parseInt(id, 10); + + // Note: parseInt stops parsing at the first non-numeric character + expect(parsedId).toBe(123); + expect(isNaN(parsedId)).toBe(false); + }); + + test('should parse negative numbers', () => { + const id = '-123'; + const parsedId = parseInt(id, 10); + + expect(parsedId).toBe(-123); + expect(isNaN(parsedId)).toBe(false); + }); + + test('should handle float strings (truncates to integer)', () => { + const id = '123.45'; + const parsedId = parseInt(id, 10); + + // Note: parseInt truncates, parseFloat would be better for floats + expect(parsedId).toBe(123); + expect(isNaN(parsedId)).toBe(false); + }); + + test('should handle leading zeros', () => { + const id = '00123'; + const parsedId = parseInt(id, 10); + + expect(parsedId).toBe(123); + expect(isNaN(parsedId)).toBe(false); + }); + }); + + describe('ID validation patterns', () => { + test('should detect invalid ID for database queries', () => { + // Note: parseInt behavior - stops at first non-numeric char + const testCases = [ + { input: 'abc', shouldParseAsNaN: true, description: 'non-numeric string' }, + { input: '', shouldParseAsNaN: true, description: 'empty string' }, + { input: '123abc', shouldParseAsNaN: false, description: 'numeric prefix (parseInt stops at "a")' }, + { input: '123.45', shouldParseAsNaN: false, description: 'float string (truncates to 123)' }, + { input: '123', shouldParseAsNaN: false, description: 'valid numeric string' }, + { input: '0', shouldParseAsNaN: false, description: 'zero' }, + { input: '-123', shouldParseAsNaN: false, description: 'negative number' }, + ]; + + testCases.forEach(({ input, shouldParseAsNaN, description }) => { + const parsedId = parseInt(input, 10); + const isNaNResult = isNaN(parsedId); + + expect(isNaNResult).toBe(shouldParseAsNaN); + }); + }); + }); + + describe('URL parameter validation', () => { + test('should validate tournament ID from URL params', () => { + const params = { id: '123' }; + const tournamentId = parseInt(params.id, 10); + + expect(isNaN(tournamentId)).toBe(false); + expect(tournamentId).toBe(123); + }); + + test('should detect invalid tournament ID from URL params', () => { + const params = { id: 'invalid' }; + const tournamentId = parseInt(params.id, 10); + + expect(isNaN(tournamentId)).toBe(true); + }); + + test('should validate player ID from URL params', () => { + const params = { id: '456' }; + const playerId = parseInt(params.id, 10); + + expect(isNaN(playerId)).toBe(false); + expect(playerId).toBe(456); + }); + + test('should detect invalid player ID from URL params', () => { + const params = { id: 'not-a-number' }; + const playerId = parseInt(params.id, 10); + + expect(isNaN(playerId)).toBe(true); + }); + }); +});