Skip to content

Commit a86a3e9

Browse files
added query validation boundaries for ?theme= parameter
1 parent e6b5723 commit a86a3e9

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

app/api/streak/route.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,28 @@ describe('GET /api/streak', () => {
245245
expect(response.status).toBe(400);
246246
});
247247

248+
it('returns 400 when an invalid theme value is provided and lists allowed themes', async () => {
249+
const response = await GET(
250+
makeRequest({
251+
user: 'octocat',
252+
theme: 'nonexistent_theme_name',
253+
})
254+
);
255+
256+
expect(response.status).toBe(400);
257+
const body = await response.json();
258+
expect(body.error).toBe('Invalid parameters');
259+
expect(body.details.fieldErrors.theme).toBeDefined();
260+
const errorMessage = body.details.fieldErrors.theme[0];
261+
expect(errorMessage).toContain('Invalid theme');
262+
expect(errorMessage).toContain('Supported themes:');
263+
expect(errorMessage).toContain('auto');
264+
expect(errorMessage).toContain('random');
265+
expect(errorMessage).toContain('dark');
266+
expect(errorMessage).toContain('light');
267+
expect(fetchGitHubContributions).not.toHaveBeenCalled();
268+
});
269+
248270
it('should return 200 OK and valid SVG when the optional repo query parameter is provided', async () => {
249271
// 1. Make request with both parameters present
250272
const response = await GET(makeRequest({ user: 'octocat', repo: 'commitpulse' }));

lib/validations.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,29 @@ describe('streakParamsSchema — theme validation', () => {
786786
expect(fieldError).toContain('neon');
787787
}
788788
});
789+
790+
it('should reject nonexistent_theme_name and verify allowed themes are listed in error', () => {
791+
const result = streakParamsSchema.safeParse({
792+
user: 'octocat',
793+
theme: 'nonexistent_theme_name',
794+
});
795+
796+
expect(result.success).toBe(false);
797+
if (!result.success) {
798+
const fieldErrors = result.error.flatten().fieldErrors;
799+
expect(fieldErrors.theme).toBeDefined();
800+
const errorMessage = fieldErrors.theme?.[0];
801+
expect(errorMessage).toContain('Invalid theme');
802+
expect(errorMessage).toContain('Supported themes:');
803+
expect(errorMessage).toContain('auto');
804+
expect(errorMessage).toContain('random');
805+
expect(errorMessage).toContain('dark');
806+
expect(errorMessage).toContain('light');
807+
expect(errorMessage).toContain('neon');
808+
expect(errorMessage).toContain('github');
809+
expect(errorMessage).toContain('dracula');
810+
}
811+
});
789812
});
790813

791814
describe('streakParamsSchema — view fallback behavior', () => {

0 commit comments

Comments
 (0)