Skip to content

Commit d6e94fc

Browse files
authored
test(github): verify graceful repos fetch failure handling (JhaSourav07#1114)
## Description Fixes JhaSourav07#1060 Added test coverage verifying that `getFullDashboardData` gracefully handles repository fetch failures without crashing the dashboard. ## Pillar * [ ] 🎨 Pillar 1 — New Theme Design * [ ] 📐 Pillar 2 — Geometric SVG Improvement * [ ] 🕐 Pillar 3 — Timezone Logic Optimization * [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview Not applicable — test-only change. ## 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 (CI will fail otherwise). * [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). * [ ] 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 (no raw elements, smooth animations, correct fonts). * [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents ae97337 + babcd23 commit d6e94fc

1 file changed

Lines changed: 44 additions & 3 deletions

File tree

lib/github.test.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,47 @@ describe('getFullDashboardData', () => {
607607
const result = await getFullDashboardData('testuser');
608608
expect(result.profile.joinedDate).toMatch(/^[A-Za-z]+ \d{4}$/);
609609
});
610+
611+
it('handles repos fetch failure gracefully', async () => {
612+
vi.mocked(fetch).mockImplementation(async (url) => {
613+
const urlStr = typeof url === 'string' ? url : (url?.toString() ?? '');
614+
615+
// Repos fetch fails
616+
if (urlStr.includes('/users/octocat/repos')) {
617+
throw new Error('Repos fetch failed');
618+
}
619+
620+
// Profile fetch succeeds
621+
if (urlStr.includes('/users/octocat')) {
622+
return mockResponse({
623+
login: 'octocat',
624+
name: 'The Octocat',
625+
avatar_url: 'avatar.png',
626+
public_repos: 10,
627+
followers: 20,
628+
following: 5,
629+
created_at: '2020-01-01T00:00:00Z',
630+
});
631+
}
632+
633+
// GraphQL contributions succeed
634+
return mockResponse({
635+
data: {
636+
user: {
637+
contributionsCollection: {
638+
contributionCalendar: mockCalendar,
639+
},
640+
},
641+
},
642+
});
643+
});
644+
645+
const result = await getFullDashboardData('octocat');
646+
647+
expect(result).toBeDefined();
648+
expect(result.profile.stats.stars).toBe(0);
649+
expect(result.languages).toEqual([]);
650+
});
610651
});
611652

612653
describe('GitHub API cache behavior', () => {
@@ -813,7 +854,7 @@ describe('getOrgDashboardData', () => {
813854

814855
it('aggregates org data correctly', async () => {
815856
vi.mocked(fetch).mockImplementation(async (url) => {
816-
const urlStr = url.toString();
857+
const urlStr = typeof url === 'string' ? url : (url?.toString() ?? '');
817858
if (urlStr.includes('/orgs/vercel/members')) return mockResponse([{ login: 'alice' }]);
818859
if (urlStr.includes('/users/vercel/repos')) return mockResponse([{ stargazers_count: 100 }]);
819860
if (urlStr.includes('/users/vercel'))
@@ -838,7 +879,7 @@ describe('getOrgDashboardData', () => {
838879

839880
it('throws an error if the target is a User instead of an Organization', async () => {
840881
vi.mocked(fetch).mockImplementation(async (url) => {
841-
const urlStr = url.toString();
882+
const urlStr = typeof url === 'string' ? url : (url?.toString() ?? '');
842883
// Specifically catch the repos and members endpoints so they return valid arrays
843884
if (urlStr.includes('/orgs/notanorg/members')) return mockResponse([]);
844885
if (urlStr.includes('/users/notanorg/repos')) return mockResponse([]);
@@ -865,7 +906,7 @@ describe('getWrappedData', () => {
865906

866907
it('returns wrapped statistics and top language correctly', async () => {
867908
vi.mocked(fetch).mockImplementation(async (url) => {
868-
const urlStr = url.toString();
909+
const urlStr = typeof url === 'string' ? url : (url?.toString() ?? '');
869910
// Return 2 TS repos, 1 Rust repo
870911
if (urlStr.includes('/repos'))
871912
return mockResponse([

0 commit comments

Comments
 (0)