Skip to content

Commit b619b31

Browse files
authored
fix(api): correct malformed stale-while-revalidate cache header (JhaSourav07#700)
## Description Fixes JhaSourav07#620 Fixes the malformed `Cache-Control` header in the GitHub API route by adding an explicit numeric value for the `stale-while-revalidate` directive. The previous response header used: `s-maxage=3600, stale-while-revalidate` which is not standards-compliant and may cause inconsistent CDN/browser caching behavior. This PR updates the header to: `s-maxage=3600, stale-while-revalidate=86400` while preserving the existing cache strategy and refresh behavior. --- ## Pillar * [x] 🛠️ Other (Bug fix, refactoring, docs) --- ## Visual Preview N/A — this PR only modifies API caching behavior and test coverage. No SVG/UI changes were made. --- ## Changes Made * Fixed malformed `Cache-Control` header syntax in the GitHub API route * Added regression tests for cache header validation * Added test coverage for refresh cache bypass behavior * Preserved existing API response and caching logic --- ## Validation * `npm run format` ✅ * `npm run lint` ✅ * `npm run test` ✅ (277 tests passing) --- ## Notes A live end-to-end header verification against the local dev server could not be completed because GitHub credentials were not configured locally, causing the endpoint to return a development-time `500` response. However: * route-level tests pass successfully * cache header behavior is validated through automated regression tests --- ## Checklist before requesting a review: * [x] I have read the `CONTRIBUTING.md` file. * [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). * [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 started the repo. * [x] I have made sure that I have only one commit to merge in this PR.
2 parents f9e89d2 + 13abd85 commit b619b31

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

app/api/github/route.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
2+
import { GET } from './route';
3+
4+
vi.mock('@/lib/github', () => ({
5+
getFullDashboardData: vi.fn(),
6+
}));
7+
8+
import { getFullDashboardData } from '@/lib/github';
9+
10+
function makeRequest(params: Record<string, string> = {}): Request {
11+
const url = new URL('http://localhost/api/github');
12+
13+
for (const [key, value] of Object.entries(params)) {
14+
url.searchParams.set(key, value);
15+
}
16+
17+
return new Request(url.toString());
18+
}
19+
20+
describe('GET /api/github', () => {
21+
beforeEach(() => {
22+
vi.clearAllMocks();
23+
vi.mocked(getFullDashboardData).mockResolvedValue({
24+
profile: { username: 'octocat' },
25+
repositories: [],
26+
languages: [],
27+
insights: [],
28+
commitClock: [],
29+
} as never);
30+
});
31+
32+
it('returns a standards-compliant Cache-Control header', async () => {
33+
const response = await GET(makeRequest({ username: 'octocat' }));
34+
35+
expect(response.status).toBe(200);
36+
expect(response.headers.get('Cache-Control')).toBe(
37+
's-maxage=3600, stale-while-revalidate=86400'
38+
);
39+
});
40+
41+
it('bypasses cache with refresh=true', async () => {
42+
const response = await GET(makeRequest({ username: 'octocat', refresh: 'true' }));
43+
44+
expect(response.headers.get('Cache-Control')).toBe('no-cache, no-store, must-revalidate');
45+
expect(getFullDashboardData).toHaveBeenCalledWith('octocat', { bypassCache: true });
46+
});
47+
});

app/api/github/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export async function GET(request: Request) {
3737
const data = await getFullDashboardData(username, { bypassCache: refresh });
3838
const cacheControl = refresh
3939
? 'no-cache, no-store, must-revalidate'
40-
: 's-maxage=3600, stale-while-revalidate';
40+
: 's-maxage=3600, stale-while-revalidate=86400';
4141

4242
return NextResponse.json(data, {
4343
status: 200,

0 commit comments

Comments
 (0)