Skip to content

Commit fed3c34

Browse files
authored
test(utils): add verification for username truncation over 30 chars (JhaSourav07#1724)
## Description Fixes JhaSourav07#1553 ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview ## 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 d615eda + db17f3f commit fed3c34

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

lib/svg/generator.test.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,4 +1355,53 @@ describe('Radar Scan Line Animation Alignment', () => {
13551355
expect(svg).toContain('width="600"');
13561356
expect(svg).toContain('height="420"');
13571357
});
1358+
1359+
it('safely truncates usernames longer than 30 chars with trailing dots without changing CSS geometry', () => {
1360+
// 1. Arrange: Create usernames (one short baseline, one strictly > 30 chars)
1361+
const shortUsername = 'avi';
1362+
const longUsername = 'ThisIsAVeryLongUsernameThatExceedsThirtyCharacters';
1363+
const expectedTruncated = longUsername.slice(0, 12) + '...';
1364+
1365+
const paramsBaseline = {
1366+
user: shortUsername,
1367+
size: 'medium',
1368+
autoTheme: false,
1369+
} as unknown as BadgeParams;
1370+
const paramsLong = {
1371+
user: longUsername,
1372+
size: 'medium',
1373+
autoTheme: false,
1374+
} as unknown as BadgeParams;
1375+
1376+
// 2. Act: Truncate username and generate SVGs
1377+
const truncatedName = truncateUsername(longUsername);
1378+
const svgBaseline = generateSVG(mockStats, paramsBaseline, mockCalendar);
1379+
const svgLong = generateSVG(mockStats, paramsLong, mockCalendar);
1380+
1381+
// Helper to extract critical SVG geometry attributes
1382+
const extractGeometry = (svgStr: string) => {
1383+
const width = svgStr.match(/width="([^"]*)"/)?.[1];
1384+
const height = svgStr.match(/height="([^"]*)"/)?.[1];
1385+
const viewBox = svgStr.match(/viewBox="([^"]*)"/)?.[1];
1386+
return { width, height, viewBox };
1387+
};
1388+
1389+
// 3. Assertions:
1390+
1391+
// A. Verify exact expected truncation value on the helper utility
1392+
expect(truncatedName).toBe(expectedTruncated);
1393+
1394+
// B. Verify the visible <text class="title"> tag contains exactly the truncated name and NOT the full username
1395+
const textTitleMatch = svgLong.match(/<text[^>]*class="title"[^>]*>([^<]*)<\/text>/);
1396+
expect(textTitleMatch).not.toBeNull();
1397+
const renderedTitleText = textTitleMatch?.[1];
1398+
1399+
expect(renderedTitleText).toBe(expectedTruncated.toUpperCase());
1400+
expect(renderedTitleText).not.toContain(longUsername.toUpperCase());
1401+
1402+
// C. Verify geometry remains completely unchanged compared to the baseline
1403+
const geometryBaseline = extractGeometry(svgBaseline);
1404+
const geometryLong = extractGeometry(svgLong);
1405+
expect(geometryLong).toEqual(geometryBaseline);
1406+
});
13581407
});

0 commit comments

Comments
 (0)