Skip to content

Commit ba975ab

Browse files
refactor(github): extract insights generation into standalone buildIn… (JhaSourav07#766)
## Description Fixes JhaSourav07#298 Extracted insight generation logic into a standalone `buildInsights()` helper. Added independent tests for: - streak > 3 path - streak ≤ 3 path - missing language fallback `getFullDashboardData()` now delegates to `buildInsights()`. ## Pillar - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview N/A — backend refactor only. ## 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 test locally. - [x] My commits follow Conventional Commits format.
1 parent 700dd04 commit ba975ab

2 files changed

Lines changed: 91 additions & 45 deletions

File tree

lib/github.test.ts

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
GITHUB_CACHE_TTL_MS,
1010
validateGitHubUsername,
1111
cacheKey,
12-
buildCommitClock,
12+
buildInsights,
1313
fetchOrgMembers,
1414
getOrgDashboardData,
1515
getWrappedData,
@@ -455,8 +455,6 @@ describe('getFullDashboardData', () => {
455455
{ name: 'Rust', percentage: 33, color: '#dea584' },
456456
]);
457457
expect(result.insights).toBeDefined();
458-
expect(result.commitClock).toBeDefined();
459-
expect(result.commitClock).toHaveLength(7);
460458
});
461459

462460
it('maps contribution counts to correct intensity levels', async () => {
@@ -670,27 +668,44 @@ describe('cacheKey', () => {
670668
expect(cacheKey('contributions', 'DeepSikha', '2025')).toBe('contributions:deepsikha:2025');
671669
});
672670
});
671+
describe('buildInsights', () => {
672+
it('uses active streak message when current streak > 3', () => {
673+
const result = buildInsights(
674+
{
675+
totalContributions: 120,
676+
currentStreak: 7,
677+
longestStreak: 20,
678+
},
679+
[{ name: 'TypeScript' }]
680+
);
673681

674-
describe('buildCommitClock', () => {
675-
it('aggregates commits correctly by day of week', () => {
676-
const allDays = [
677-
{ date: '2024-06-09', contributionCount: 2 }, // Sun
678-
{ date: '2024-06-10', contributionCount: 5 }, // Mon
679-
{ date: '2024-06-10', contributionCount: 3 }, // Mon
680-
{ date: '2024-06-12', contributionCount: 4 }, // Wed
681-
];
682-
683-
const result = buildCommitClock(allDays);
684-
685-
expect(result).toEqual([
686-
{ day: 'Sun', commits: 2 },
687-
{ day: 'Mon', commits: 8 },
688-
{ day: 'Tue', commits: 0 },
689-
{ day: 'Wed', commits: 4 },
690-
{ day: 'Thu', commits: 0 },
691-
{ day: 'Fri', commits: 0 },
692-
{ day: 'Sat', commits: 0 },
693-
]);
682+
expect(result[2].text).toContain('active 7-day streak');
683+
});
684+
685+
it('uses longest streak message when current streak <= 3', () => {
686+
const result = buildInsights(
687+
{
688+
totalContributions: 120,
689+
currentStreak: 2,
690+
longestStreak: 15,
691+
},
692+
[{ name: 'Rust' }]
693+
);
694+
695+
expect(result[2].text).toContain('15 days');
696+
});
697+
698+
it('falls back to Unknown when languages list is empty', () => {
699+
const result = buildInsights(
700+
{
701+
totalContributions: 50,
702+
currentStreak: 1,
703+
longestStreak: 5,
704+
},
705+
[]
706+
);
707+
708+
expect(result[1].text).toContain('Unknown');
694709
});
695710
});
696711

lib/github.ts

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,46 @@ export function generateAchievements(totalContributions: number, currentStreak:
452452
}
453453
return achievements;
454454
}
455+
type StreakStats = {
456+
totalContributions: number;
457+
currentStreak: number;
458+
longestStreak: number;
459+
};
460+
461+
type Language = {
462+
name: string;
463+
};
464+
465+
export function buildInsights(streakStats: StreakStats, languages: Language[]) {
466+
const insights = [
467+
{
468+
id: '1',
469+
icon: 'Flame',
470+
text: `You have a total of ${streakStats.totalContributions} contributions this year.`,
471+
},
472+
{
473+
id: '2',
474+
icon: 'Code',
475+
text: `Your primary language is ${languages[0]?.name || 'Unknown'}.`,
476+
},
477+
];
478+
479+
if (streakStats.currentStreak > 3) {
480+
insights.push({
481+
id: '3',
482+
icon: 'Zap',
483+
text: `You are currently on an active ${streakStats.currentStreak}-day streak! Keep it going!`,
484+
});
485+
} else {
486+
insights.push({
487+
id: '3',
488+
icon: 'Star',
489+
text: `Your longest coding streak is ${streakStats.longestStreak} days!`,
490+
});
491+
}
492+
493+
return insights;
494+
}
455495

456496
export function buildCommitClock(allDays: ContributionDay[]) {
457497
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
@@ -553,29 +593,20 @@ export async function getFullDashboardData(username: string, options: FetchOptio
553593
streakStats.currentStreak
554594
);
555595

556-
const insights = [
557-
{
558-
id: '1',
559-
icon: 'Flame',
560-
text: `You have a total of ${streakStats.totalContributions} contributions this year.`,
561-
},
562-
{ id: '2', icon: 'Code', text: `Your primary language is ${languages[0]?.name || 'Unknown'}.` },
563-
];
564-
if (streakStats.currentStreak > 3) {
565-
insights.push({
566-
id: '3',
567-
icon: 'Zap',
568-
text: `You are currently on an active ${streakStats.currentStreak}-day streak! Keep it going!`,
569-
});
570-
} else {
571-
insights.push({
572-
id: '3',
573-
icon: 'Star',
574-
text: `Your longest coding streak is ${streakStats.longestStreak} days!`,
575-
});
576-
}
596+
// 4. Insights Generation
597+
const insights = buildInsights(streakStats, languages);
577598

578-
const commitClock = buildCommitClock(allDays);
599+
// Aggregate real contribution data by day of week from the already-fetched calendar
600+
const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
601+
const dayTotals = new Array(7).fill(0);
602+
for (const day of allDays) {
603+
const dow = new Date(day.date).getUTCDay();
604+
dayTotals[dow] += day.contributionCount;
605+
}
606+
const commitClock = dayNames.map((name, i) => ({
607+
day: name,
608+
commits: dayTotals[i],
609+
}));
579610

580611
return {
581612
profile,

0 commit comments

Comments
 (0)