Skip to content

Commit 1812392

Browse files
authored
test(api validation): check query validation boundaries for ?layout= parameter (Variation 4) (JhaSourav07#1957)
## Description Fixes JhaSourav07#1456 This PR adds query validation boundaries for the `?layout=` parameter in `streakParamsSchema` to return a 400 Bad Request if an unsupported value is supplied. It also adds unit tests and integration tests. ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview None (Validation changes) ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally. - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors. - [x] My commits follow the Conventional Commits format. - [x] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard.
2 parents b99ea5c + 0bb94f4 commit 1812392

2 files changed

Lines changed: 83 additions & 1 deletion

File tree

app/api/streak/route.test.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,21 @@ describe('GET /api/streak', () => {
149149
expect(response.status).toBe(400);
150150
const body = await response.json();
151151
expect(body.error).toBe('Invalid parameters');
152-
expect(body.details).not.toBeNull();
152+
});
153+
154+
it('returns 400 Bad Request when ?layout= is set to an unsupported format (Variation 4)', async () => {
155+
const response = await GET(
156+
makeRequest({
157+
user: 'octocat',
158+
layout: 'unsupported_layout',
159+
})
160+
);
161+
162+
expect(response.status).toBe(400);
163+
const body = await response.json();
164+
expect(body.details.fieldErrors.layout[0]).toContain(
165+
'Invalid layout format. Supported values: default, compact, full.'
166+
);
153167
});
154168

155169
it('returns 400 when the user parameter is missing', async () => {

lib/validations.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,3 +1182,71 @@ describe('streakParamsSchema — date query validation boundaries (Variation 4)'
11821182
expect(result.success).toBe(true);
11831183
});
11841184
});
1185+
1186+
/* ==========================================================================
1187+
* LAYOUT PARAMETER — QUERY VALIDATION BOUNDARIES (VARIATION 4)
1188+
* ========================================================================== */
1189+
1190+
describe('streakParamsSchema — layout query validation boundaries (Variation 4)', () => {
1191+
it('rejects unsupported_layout and marks the parse as failed', () => {
1192+
const result = streakParamsSchema.safeParse({
1193+
user: 'octocat',
1194+
layout: 'unsupported_layout',
1195+
});
1196+
1197+
expect(result.success).toBe(false);
1198+
});
1199+
1200+
it('surfaces a meaningful error message for unsupported_layout', () => {
1201+
const result = streakParamsSchema.safeParse({
1202+
user: 'octocat',
1203+
layout: 'unsupported_layout',
1204+
});
1205+
1206+
expect(result.success).toBe(false);
1207+
if (!result.success) {
1208+
const messages = result.error.issues.map((i) => i.message).join(' ');
1209+
expect(messages).toContain(
1210+
'Invalid layout format. Supported values: default, compact, full.'
1211+
);
1212+
}
1213+
});
1214+
1215+
it('accepts "default" as a valid layout value', () => {
1216+
const result = streakParamsSchema.safeParse({
1217+
user: 'octocat',
1218+
layout: 'default',
1219+
});
1220+
1221+
expect(result.success).toBe(true);
1222+
});
1223+
1224+
it('accepts "compact" as a valid layout value', () => {
1225+
const result = streakParamsSchema.safeParse({
1226+
user: 'octocat',
1227+
layout: 'compact',
1228+
});
1229+
1230+
expect(result.success).toBe(true);
1231+
});
1232+
1233+
it('accepts "full" as a valid layout value', () => {
1234+
const result = streakParamsSchema.safeParse({
1235+
user: 'octocat',
1236+
layout: 'full',
1237+
});
1238+
1239+
expect(result.success).toBe(true);
1240+
});
1241+
1242+
it('treats omitted layout as undefined (no validation error)', () => {
1243+
const result = streakParamsSchema.safeParse({
1244+
user: 'octocat',
1245+
});
1246+
1247+
expect(result.success).toBe(true);
1248+
if (result.success) {
1249+
expect(result.data.layout).toBeUndefined();
1250+
}
1251+
});
1252+
});

0 commit comments

Comments
 (0)