diff --git a/app/api/streak/route.test.ts b/app/api/streak/route.test.ts index c81ca19b..4aebf7b8 100644 --- a/app/api/streak/route.test.ts +++ b/app/api/streak/route.test.ts @@ -650,6 +650,14 @@ describe('GET /api/streak', () => { expect(response.status).toBe(400); expect(body.details.fieldErrors.date[0]).toContain('Invalid "date" format'); }); + + it('returns 400 when an invalid ISO8601 calendar date format like "2026-15-40" is supplied (Variation 4)', async () => { + const response = await GET(makeRequest({ user: 'octocat', date: '2026-15-40' })); + const body = await response.json(); + + expect(response.status).toBe(400); + expect(body.details.fieldErrors.date[0]).toContain('Invalid "date" format. Use ISO 8601.'); + }); }); }); diff --git a/lib/validations.test.ts b/lib/validations.test.ts index 6cf61a05..4ed8a45e 100644 --- a/lib/validations.test.ts +++ b/lib/validations.test.ts @@ -1061,3 +1061,31 @@ describe('streakParamsSchema user maxLength validation boundaries (Variation 3)' expect(parseResult.success).toBe(true); }); }); + +/* ========================================================================== + * DATE PARAMETER — QUERY VALIDATION BOUNDARIES (VARIATION 4) + * ========================================================================== */ + +describe('streakParamsSchema — date query validation boundaries (Variation 4)', () => { + it('rejects an invalid date format like "2026-15-40"', () => { + const result = streakParamsSchema.safeParse({ + user: 'octocat', + date: '2026-15-40', + }); + + expect(result.success).toBe(false); + if (!result.success) { + const messages = result.error.issues.map((i) => i.message).join(' '); + expect(messages).toContain('Invalid "date" format. Use ISO 8601.'); + } + }); + + it('accepts a valid ISO8601 date', () => { + const result = streakParamsSchema.safeParse({ + user: 'octocat', + date: '2026-05-30', + }); + + expect(result.success).toBe(true); + }); +});