Skip to content

Commit c72ec0e

Browse files
committed
Remove semicolons and add comprehensive tests
1 parent 39c195b commit c72ec0e

7 files changed

Lines changed: 3878 additions & 20 deletions

File tree

.cursor/rules/swipecast.mdc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
alwaysApply: true
3+
---
4+
- use snake case for file naming
5+
- avoid using ";"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
node_modules
22
dist
3+
coverage
34
*.log
45
.DS_Store
56
.idea

__tests__/stripe_helpers.test.ts

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
import {
2+
StripeHelpers,
3+
StripeCard,
4+
StripeUSBankAccount,
5+
StripePaymentMethod,
6+
StripeCustomer,
7+
} from '../src/helpers/stripe_helpers'
8+
9+
describe('StripeHelpers', () => {
10+
describe('getCardBrandLabel', () => {
11+
it('should format American Express as Amex', () => {
12+
const card: StripeCard = {
13+
brand: 'American Express',
14+
last4: '1234',
15+
exp_month: 12,
16+
exp_year: 2025,
17+
}
18+
expect(StripeHelpers.getCardBrandLabel(card)).toBe('Amex')
19+
})
20+
21+
it('should format Visa correctly', () => {
22+
const card: StripeCard = {
23+
brand: 'Visa',
24+
last4: '1234',
25+
exp_month: 12,
26+
exp_year: 2025,
27+
}
28+
expect(StripeHelpers.getCardBrandLabel(card)).toBe('Visa')
29+
})
30+
31+
it('should format Mastercard correctly', () => {
32+
const card: StripeCard = {
33+
brand: 'Mastercard',
34+
last4: '1234',
35+
exp_month: 12,
36+
exp_year: 2025,
37+
}
38+
expect(StripeHelpers.getCardBrandLabel(card)).toBe('Mastercard')
39+
})
40+
41+
it('should capitalize unknown brands', () => {
42+
const card: StripeCard = {
43+
brand: 'visa',
44+
last4: '1234',
45+
exp_month: 12,
46+
exp_year: 2025,
47+
}
48+
expect(StripeHelpers.getCardBrandLabel(card)).toBe('Visa')
49+
})
50+
51+
it('should handle empty brand', () => {
52+
const card: StripeCard = {
53+
brand: '',
54+
last4: '1234',
55+
exp_month: 12,
56+
exp_year: 2025,
57+
}
58+
expect(StripeHelpers.getCardBrandLabel(card)).toBe('')
59+
})
60+
61+
it('should handle missing brand', () => {
62+
const card: StripeCard = {
63+
brand: undefined as any,
64+
last4: '1234',
65+
exp_month: 12,
66+
exp_year: 2025,
67+
}
68+
expect(StripeHelpers.getCardBrandLabel(card)).toBe('')
69+
})
70+
})
71+
72+
describe('getCardLabel', () => {
73+
it('should format card label correctly', () => {
74+
const card: StripeCard = {
75+
brand: 'Visa',
76+
last4: '1234',
77+
exp_month: 12,
78+
exp_year: 2025,
79+
}
80+
expect(StripeHelpers.getCardLabel(card)).toBe('Visa •••• 1234 · exp 12/2025')
81+
})
82+
83+
it('should handle single digit month', () => {
84+
const card: StripeCard = {
85+
brand: 'Mastercard',
86+
last4: '5678',
87+
exp_month: 1,
88+
exp_year: 2026,
89+
}
90+
expect(StripeHelpers.getCardLabel(card)).toBe('Mastercard •••• 5678 · exp 1/2026')
91+
})
92+
})
93+
94+
describe('getUSBankAccountLabel', () => {
95+
it('should format bank account label correctly', () => {
96+
const account: StripeUSBankAccount = {
97+
bank_name: 'Chase',
98+
last4: '1234',
99+
}
100+
expect(StripeHelpers.getUSBankAccountLabel(account)).toBe('Chase · *1234')
101+
})
102+
103+
it('should handle different bank names', () => {
104+
const account: StripeUSBankAccount = {
105+
bank_name: 'Bank of America',
106+
last4: '5678',
107+
}
108+
expect(StripeHelpers.getUSBankAccountLabel(account)).toBe('Bank of America · *5678')
109+
})
110+
})
111+
112+
describe('getPaymentMethodLabel', () => {
113+
it('should format card payment method', () => {
114+
const pm: StripePaymentMethod = {
115+
data: {
116+
type: 'card',
117+
card: {
118+
brand: 'Visa',
119+
last4: '1234',
120+
exp_month: 12,
121+
exp_year: 2025,
122+
},
123+
},
124+
}
125+
expect(StripeHelpers.getPaymentMethodLabel(pm)).toBe('Visa •••• 1234 · exp 12/2025')
126+
})
127+
128+
it('should format bank account payment method', () => {
129+
const pm: StripePaymentMethod = {
130+
data: {
131+
type: 'us_bank_account',
132+
us_bank_account: {
133+
bank_name: 'Chase',
134+
last4: '1234',
135+
},
136+
},
137+
}
138+
expect(StripeHelpers.getPaymentMethodLabel(pm)).toBe('Chase · *1234')
139+
})
140+
141+
it('should return Unknown Card for invalid payment method', () => {
142+
const pm: StripePaymentMethod = {
143+
data: {
144+
type: 'card',
145+
},
146+
}
147+
expect(StripeHelpers.getPaymentMethodLabel(pm)).toBe('Unknown Card')
148+
})
149+
})
150+
151+
describe('getCustomerDefaultPaymentMethod', () => {
152+
it('should return null for null customer', () => {
153+
expect(StripeHelpers.getCustomerDefaultPaymentMethod(null)).toBeNull()
154+
})
155+
156+
it('should return null for customer without data', () => {
157+
const customer: StripeCustomer = {
158+
data: {},
159+
}
160+
expect(StripeHelpers.getCustomerDefaultPaymentMethod(customer)).toBeNull()
161+
})
162+
163+
it('should extract default card payment method from customer', () => {
164+
const customer: StripeCustomer = {
165+
data: {
166+
invoice_settings: {
167+
default_payment_method: {
168+
id: 'pm_123',
169+
type: 'card',
170+
object: 'payment_method',
171+
card: {
172+
brand: 'Visa',
173+
last4: '1234',
174+
exp_month: 12,
175+
exp_year: 2025,
176+
},
177+
},
178+
},
179+
},
180+
}
181+
182+
const result = StripeHelpers.getCustomerDefaultPaymentMethod(customer)
183+
expect(result).not.toBeNull()
184+
expect(result?.isPaymentMethod).toBe(true)
185+
expect(result?.last4).toBe('1234')
186+
expect(result?.expMonth).toBe(12)
187+
expect(result?.expYear).toBe(2025)
188+
expect(result?.brand).toBe('Visa')
189+
expect(result?.id).toBe('pm_123')
190+
expect(result?.label).toBe('Visa •••• 1234 · exp 12/2025')
191+
})
192+
193+
it('should extract default US bank account payment method from customer', () => {
194+
const customer: StripeCustomer = {
195+
data: {
196+
invoice_settings: {
197+
default_payment_method: {
198+
id: 'pm_456',
199+
type: 'us_bank_account',
200+
object: 'payment_method',
201+
us_bank_account: {
202+
bank_name: 'Chase',
203+
last4: '5678',
204+
},
205+
},
206+
},
207+
},
208+
}
209+
210+
const result = StripeHelpers.getCustomerDefaultPaymentMethod(customer)
211+
expect(result).not.toBeNull()
212+
expect(result?.isPaymentMethod).toBe(true)
213+
expect(result?.last4).toBe('5678')
214+
expect(result?.bankName).toBe('Chase')
215+
expect(result?.id).toBe('pm_456')
216+
expect(result?.label).toBe('Chase · *5678')
217+
})
218+
219+
it('should fallback to source when no default payment method', () => {
220+
const customer: StripeCustomer = {
221+
data: {
222+
sources: {
223+
data: [
224+
{
225+
brand: 'Mastercard',
226+
last4: '9999',
227+
exp_month: 6,
228+
exp_year: 2027,
229+
id: 'card_123',
230+
object: 'card',
231+
},
232+
],
233+
},
234+
},
235+
}
236+
237+
const result = StripeHelpers.getCustomerDefaultPaymentMethod(customer)
238+
expect(result).not.toBeNull()
239+
expect(result?.isPaymentMethod).toBe(false)
240+
expect(result?.last4).toBe('9999')
241+
expect(result?.expMonth).toBe(6)
242+
expect(result?.expYear).toBe(2027)
243+
expect(result?.brand).toBe('Mastercard')
244+
expect(result?.id).toBe('card_123')
245+
expect(result?.label).toBe('Mastercard •••• 9999 · exp 6/2027')
246+
})
247+
248+
it('should return fallback card when useFallback is true', () => {
249+
const customer: StripeCustomer = {
250+
data: {},
251+
}
252+
253+
const result = StripeHelpers.getCustomerDefaultPaymentMethod(customer, true)
254+
expect(result).not.toBeNull()
255+
expect(result?.isPaymentMethod).toBe(false)
256+
expect(result?.last4).toBe('XXXX')
257+
expect(result?.expMonth).toBe(0)
258+
expect(result?.expYear).toBe(0)
259+
expect(result?.brand).toBe('Unknown')
260+
expect(result?.id).toBe('N/A')
261+
expect(result?.label).toBe('Unknown Card')
262+
})
263+
264+
it('should return null when no payment method and useFallback is false', () => {
265+
const customer: StripeCustomer = {
266+
data: {},
267+
}
268+
269+
const result = StripeHelpers.getCustomerDefaultPaymentMethod(customer, false)
270+
expect(result).toBeNull()
271+
})
272+
273+
it('should handle missing optional fields in card', () => {
274+
const customer: StripeCustomer = {
275+
data: {
276+
invoice_settings: {
277+
default_payment_method: {
278+
id: 'pm_789',
279+
type: 'card',
280+
card: {
281+
brand: 'Visa',
282+
last4: undefined,
283+
exp_month: undefined,
284+
exp_year: undefined,
285+
},
286+
},
287+
},
288+
},
289+
}
290+
291+
const result = StripeHelpers.getCustomerDefaultPaymentMethod(customer)
292+
expect(result).not.toBeNull()
293+
expect(result?.last4).toBe('')
294+
expect(result?.expMonth).toBeUndefined()
295+
expect(result?.expYear).toBeUndefined()
296+
})
297+
})
298+
})
299+

jest.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
roots: ['<rootDir>/src', '<rootDir>/__tests__'],
5+
testMatch: ['**/__tests__/**/*.test.ts', '**/?(*.)+(spec|test).ts'],
6+
collectCoverageFrom: [
7+
'src/**/*.ts',
8+
'!src/**/*.d.ts',
9+
],
10+
coverageDirectory: 'coverage',
11+
coverageReporters: ['text', 'lcov', 'html'],
12+
}
13+

0 commit comments

Comments
 (0)