Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions lib/rss.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, it, expect, vi } from 'vitest';
import { fetchLatestArticles } from './rss';

// Mock rss-parser so it doesn't make real network requests during tests
vi.mock('rss-parser', () => {
return {
default: class MockParser {
parseURL = vi.fn().mockResolvedValue({
items: [
{
title: 'Test Post',
link: 'https://dev.to/test',
pubDate: '2026-06-15T00:00:00Z',
},
],
});
},
};
});

describe('rss / fetchLatestArticles', () => {
it('[Bug fix] formats pubDate deterministically regardless of Node process locale', async () => {
// Because rss-parser is mocked above, this will reliably return the mock item
const articles = await fetchLatestArticles('devto', 'testuser');

expect(articles).toHaveLength(1);
// This verifies the 'en-US' Date locale change correctly generates "Jun 15, 2026"
expect(articles[0].pubDate).toBe('Jun 15, 2026');
});
});
6 changes: 5 additions & 1 deletion lib/rss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@ export async function fetchLatestArticles(
const articles = feed.items.slice(0, 3).map((item) => ({
title: item.title || 'Untitled',
link: item.link || '',
// Explicit 'en-US' locale, matching the pattern already used in
// lib/github.ts's joinedDate formatting β€” this string is baked
// server-side into the generated SVG, so it must be deterministic
// regardless of the server's ambient runtime locale/ICU build.
pubDate: item.pubDate
? new Date(item.pubDate).toLocaleDateString(undefined, {
? new Date(item.pubDate).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
Expand Down
32 changes: 32 additions & 0 deletions lib/svg/repoSpotlight.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { describe, it, expect } from 'vitest';
import { generateRepoSpotlightSVG } from './repoSpotlight';
import { GitHubRepo } from '@/lib/github';
import { BadgeParams } from '@/types';

describe('generateRepoSpotlightSVG', () => {
it('[Bug fix] formats pushed_at with a fixed, explicit locale', () => {
// Construct a minimal mocked repository to satisfy the function requirements
const mockRepo = {
name: 'test-repo',
description: 'A test repository',
language: 'TypeScript',
stargazers_count: 100,
forks_count: 50,
pushed_at: '2026-06-15T00:00:00Z',
participation: [0, 5, 10, 5, 0],
} as GitHubRepo;

// Provide default mockup formatting arguments
const mockParams = {
bg: 'ffffff',
text: '000000',
accent: 'ff0000',
radius: 4,
} as BadgeParams;

const svg = generateRepoSpotlightSVG(mockRepo, mockParams);

// Check that our forced date outputs perfectly in the generated SVG
expect(svg).toContain('Updated Jun 15, 2026');
});
});
3 changes: 2 additions & 1 deletion lib/svg/repoSpotlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export function generateRepoSpotlightSVG(repo: GitHubRepo, params: BadgeParams):

// Parse dates if available
const dateStr = repo.pushed_at
? new Date(repo.pushed_at).toLocaleDateString(undefined, {
? // Explicit 'en-US' locale β€” see lib/rss.ts for the same fix and rationale.
new Date(repo.pushed_at).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
Expand Down
6 changes: 1 addition & 5 deletions utils/dateHelpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getAuthorLocalHour, getViewerLocalHour, processCommitTimestamps } from

describe('dateHelpers', () => {
describe('getAuthorLocalHour', () => {
// ... keeping existing tests identical ...
it('extracts hour from a standard ISO timestamp with positive offset', () => {
expect(getAuthorLocalHour('2024-03-10T15:30:00+02:00')).toBe(15);
});
Expand Down Expand Up @@ -70,9 +71,6 @@ describe('dateHelpers', () => {
expect(result).toEqual({ morning: 0, afternoon: 0, evening: 0, night: 0 });
});

// NOTE: Added 'Z' to timestamp strings below to explicitly parse them as UTC,
// which aligns with processCommitTimestamps using getUTCHours() internally.

it('counts valid morning commits correctly', () => {
const result = processCommitTimestamps(['2024-03-10T09:00:00Z', '2024-03-10T11:30:00Z']);
expect(result.morning).toBe(2);
Expand Down Expand Up @@ -109,8 +107,6 @@ describe('dateHelpers', () => {
expect(result.evening).toBe(0);
});

// Regression test: verifies timezone-agnostic behavior.
// This test would fail with getHours() in IST but passes with getUTCHours().
it('produces consistent results regardless of system timezone', () => {
const timestamps = [
'2024-03-10T09:00:00Z', // 09:00 UTC = morning
Expand Down
Loading