Skip to content

Commit 75b1a2a

Browse files
authored
Merge pull request #143 from Kristyidu/fix-issue-15
Fix #15: Add Jest tests for formatting utilities
2 parents beffb3a + 301ef2f commit 75b1a2a

6 files changed

Lines changed: 111 additions & 0 deletions

File tree

issue15.json

11.2 KB
Binary file not shown.

issue32.json

11 KB
Binary file not shown.

issue33.json

11.4 KB
Binary file not shown.

issue35.json

11.1 KB
Binary file not shown.

issues_summary.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"number": 15,
4+
"title": "🧪 Add Jest tests for formatting utilities",
5+
"body": "## Problem\nNo tests exist for formatting utilities, risking incorrect display of currency, dates, and other values.\n\n## Context\nFormatting errors could cause users to see wrong prices or dates.\n\n## Proposed Solution\nCreate tests for all formatting functions:\n1. `formatCurrency` - various currencies, decimals\n2. `formatRelativeDate` - past, future, edge cases\n3. `formatBillingCycle` - all cycle types\n4. `formatCategory` - all category types\n\n## Acceptance Criteria\n- [ ] All exported functions tested\n- [ ] Edge cases covered (zero, negative, null)\n- [ ] Different locale considerations\n- [ ] All tests pass\n\n## Technical Notes\n**File:** `src/utils/__tests__/formatting.test.ts` (new)\n**Current:** `src/utils/formatting.ts`\n\n## Constraints\n- Test both positive and negative scenarios\n- Test boundary conditions"
6+
},
7+
{
8+
"number": 32,
9+
"title": "🔧 Remove unsafe any types from API details",
10+
"body": "## Problem\ndetails?: any in api.ts loses type safety for API responses.\n\n## Context\nAPI responses are parsed without type checking, risking runtime errors.\n\n## Proposed Solution\nDefine proper API types:\n1. Create response interfaces for each endpoint\n2. Replace any with specific types\n3. Add JSON schema validation\n4. Consider using zod for runtime validation\n\n## Acceptance Criteria\n- [ ] All API types properly defined\n- [ ] Response parsing type-safe\n- [ ] IDE autocomplete for API data\n- [ ] Build passes without errors\n\n## Technical Notes\n**File:** src/types/api.ts:49\n**Type:** SubscriptionAPIResponse\n\n## Constraints\n- Handle nullable fields\n- Version API responses if needed\n- Document unknown fields"
11+
},
12+
{
13+
"number": 33,
14+
"title": "🔧 Remove unsafe type casts from HomeScreen",
15+
"body": "## Problem\nMultiple as never casts bypass TypeScript safety in HomeScreen.\n\n## Context\nType casts are code smells indicating type design problems.\n\n## Proposed Solution\nFix type issues properly:\n1. Identify all as never usages\n2. Determine correct type for each\n3. Update type definitions if needed\n4. Remove unnecessary casts\n\n## Acceptance Criteria\n- [ ] All as never casts removed\n- [ ] Proper types defined\n- [ ] TypeScript strict mode passes\n- [ ] Runtime behavior unchanged\n\n## Technical Notes\n**Files:** \n- src/screens/HomeScreen.tsx\n- src/screens/WalletConnectScreen.tsx\n\n## Constraints\n- Some casts may be necessary\n- Document why if kept\n- Test thoroughly after changes"
16+
},
17+
{
18+
"number": 35,
19+
"title": "🔍 Add proper Ethereum address validation",
20+
"body": "## Problem\nAddress validation only checks length, not format or checksum.\n\n## Context\nInvalid addresses can be entered, leading to failed transactions.\n\n## Proposed Solution\nImplement proper validation:\n1. Check for 0x prefix\n2. Validate hex characters\n3. Verify checksum (EIP-55 for mainnet)\n4. Show error for invalid addresses\n\n## Acceptance Criteria\n- [ ] Valid addresses accepted\n- [ ] Invalid format rejected with message\n- [ ] Checksum validation for mainnet\n- [ ] Test with various address formats\n\n## Technical Notes\n**File:** src/screens/CryptoPaymentScreen.tsx:107\n**Functions:** Add address validation utility\n\n## Constraints\n- Must handle testnet addresses\n- Consider mixed case addresses\n- Performance for real-time validation"
21+
}
22+
]
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import {
2+
formatCurrency,
3+
formatRelativeDate,
4+
formatBillingCycle,
5+
formatCategory
6+
} from '../formatting';
7+
import { SubscriptionCategory, BillingCycle } from '../../types/subscription';
8+
9+
describe('Formatting Utilities', () => {
10+
describe('formatCurrency', () => {
11+
it('formats USD correctly', () => {
12+
expect(formatCurrency(19.99)).toBe('$19.99');
13+
expect(formatCurrency(0)).toBe('$0.00');
14+
});
15+
16+
it('formats other currencies correctly', () => {
17+
expect(formatCurrency(19.99, 'EUR').replace(/\s/g, ' ')).toContain('19.99');
18+
expect(formatCurrency(19.99, 'GBP')).toContain('£19.99');
19+
});
20+
21+
it('handles negative values correctly', () => {
22+
expect(formatCurrency(-10.50)).toBe('-$10.50');
23+
});
24+
});
25+
26+
describe('formatRelativeDate', () => {
27+
beforeAll(() => {
28+
jest.useFakeTimers();
29+
jest.setSystemTime(new Date('2024-01-15T12:00:00Z'));
30+
});
31+
32+
afterAll(() => {
33+
jest.useRealTimers();
34+
});
35+
36+
it('returns "Today" for current date', () => {
37+
expect(formatRelativeDate(new Date('2024-01-15T15:00:00Z'))).toBe('Today');
38+
});
39+
40+
it('returns "Yesterday" for previous day', () => {
41+
expect(formatRelativeDate(new Date('2024-01-14T10:00:00Z'))).toBe('Yesterday');
42+
});
43+
44+
it('returns "Tomorrow" for next day', () => {
45+
expect(formatRelativeDate(new Date('2024-01-16T10:00:00Z'))).toBe('Tomorrow');
46+
});
47+
48+
it('formats days ago correctly', () => {
49+
expect(formatRelativeDate(new Date('2024-01-10T10:00:00Z'))).toBe('5 days ago');
50+
});
51+
52+
it('formats future days correctly', () => {
53+
expect(formatRelativeDate(new Date('2024-01-20T10:00:00Z'))).toBe('In 5 days');
54+
});
55+
});
56+
57+
describe('formatBillingCycle', () => {
58+
it('capitalizes monthly correctly', () => {
59+
expect(formatBillingCycle(BillingCycle.MONTHLY)).toBe('Monthly');
60+
});
61+
62+
it('capitalizes yearly correctly', () => {
63+
expect(formatBillingCycle(BillingCycle.YEARLY)).toBe('Yearly');
64+
});
65+
66+
it('capitalizes weekly correctly', () => {
67+
expect(formatBillingCycle(BillingCycle.WEEKLY)).toBe('Weekly');
68+
});
69+
70+
it('capitalizes custom correctly', () => {
71+
expect(formatBillingCycle(BillingCycle.CUSTOM)).toBe('Custom');
72+
});
73+
});
74+
75+
describe('formatCategory', () => {
76+
it('capitalizes streaming correctly', () => {
77+
expect(formatCategory(SubscriptionCategory.STREAMING)).toBe('Streaming');
78+
});
79+
80+
it('capitalizes software correctly', () => {
81+
expect(formatCategory(SubscriptionCategory.SOFTWARE)).toBe('Software');
82+
});
83+
84+
it('capitalizes other enum values correctly', () => {
85+
expect(formatCategory(SubscriptionCategory.FITNESS)).toBe('Fitness');
86+
expect(formatCategory(SubscriptionCategory.EDUCATION)).toBe('Education');
87+
});
88+
});
89+
});

0 commit comments

Comments
 (0)