|
4 | 4 | devLogin, |
5 | 5 | setupServer, |
6 | 6 | superRequest, |
7 | | - defaultUserEmail |
| 7 | + defaultUserEmail, |
| 8 | + defaultUserId |
8 | 9 | } from '../../jest.utils'; |
9 | 10 | import { createUserInput } from '../utils/create-user'; |
10 | 11 |
|
@@ -42,6 +43,21 @@ const userWithProgress: Prisma.userCreateInput = { |
42 | 43 | } |
43 | 44 | ] |
44 | 45 | }; |
| 46 | +const donationMock = { |
| 47 | + endDate: null, |
| 48 | + startDate: { |
| 49 | + date: '2024-07-17T10:20:56.076Z', |
| 50 | + when: '2024-07-17T10:20:56.076+00:00' |
| 51 | + }, |
| 52 | + id: '66979a414748aa2f3ba36d41', |
| 53 | + amount: 500, |
| 54 | + customerId: 'cust_test_id', |
| 55 | + duration: 'month', |
| 56 | + |
| 57 | + provider: 'stripe', |
| 58 | + subscriptionId: 'sub_test_id', |
| 59 | + userId: defaultUserId |
| 60 | +}; |
45 | 61 | const sharedDonationReqBody = { |
46 | 62 | amount: 500, |
47 | 63 | duration: 'month' |
@@ -93,6 +109,9 @@ const mockSubRetrieveObj = { |
93 | 109 | status: 'active' |
94 | 110 | }; |
95 | 111 | const mockSubRetrieve = jest.fn(() => Promise.resolve(mockSubRetrieveObj)); |
| 112 | +const mockCheckoutSessionCreate = jest.fn(() => |
| 113 | + Promise.resolve({ id: 'checkout_session_id' }) |
| 114 | +); |
96 | 115 | const mockCustomerUpdate = jest.fn(); |
97 | 116 | const generateMockSubCreate = (status: string) => () => |
98 | 117 | Promise.resolve({ |
@@ -120,15 +139,22 @@ jest.mock('stripe', () => { |
120 | 139 | subscriptions: { |
121 | 140 | create: mockSubCreate, |
122 | 141 | retrieve: mockSubRetrieve |
| 142 | + }, |
| 143 | + checkout: { |
| 144 | + sessions: { |
| 145 | + create: mockCheckoutSessionCreate |
| 146 | + } |
123 | 147 | } |
124 | 148 | }; |
125 | 149 | }); |
126 | 150 | }); |
127 | 151 |
|
128 | 152 | describe('Donate', () => { |
| 153 | + let setCookies: string[]; |
129 | 154 | setupServer(); |
130 | 155 | describe('Authenticated User', () => { |
131 | 156 | let superPost: ReturnType<typeof createSuperRequest>; |
| 157 | + let superPut: ReturnType<typeof createSuperRequest>; |
132 | 158 | const verifyUpdatedUserAndNewDonation = async (email: string) => { |
133 | 159 | const user = await fastifyTestInstance.prisma.user.findFirst({ |
134 | 160 | where: { email } |
@@ -162,8 +188,9 @@ describe('Donate', () => { |
162 | 188 | }; |
163 | 189 |
|
164 | 190 | beforeEach(async () => { |
165 | | - const setCookies = await devLogin(); |
| 191 | + setCookies = await devLogin(); |
166 | 192 | superPost = createSuperRequest({ method: 'POST', setCookies }); |
| 193 | + superPut = createSuperRequest({ method: 'PUT', setCookies }); |
167 | 194 | await fastifyTestInstance.prisma.user.updateMany({ |
168 | 195 | where: { email: userWithProgress.email }, |
169 | 196 | data: userWithProgress |
@@ -302,6 +329,39 @@ describe('Donate', () => { |
302 | 329 | }); |
303 | 330 | }); |
304 | 331 |
|
| 332 | + describe('PUT /donate/update-stripe-card', () => { |
| 333 | + it('should return 200 and return session id', async () => { |
| 334 | + await fastifyTestInstance.prisma.donation.create({ |
| 335 | + data: donationMock |
| 336 | + }); |
| 337 | + const response = await superPut('/donate/update-stripe-card').send({}); |
| 338 | + expect(mockCheckoutSessionCreate).toHaveBeenCalledWith({ |
| 339 | + cancel_url: 'http://localhost:8000/update-stripe-card', |
| 340 | + customer: 'cust_test_id', |
| 341 | + mode: 'setup', |
| 342 | + payment_method_types: ['card'], |
| 343 | + setup_intent_data: { |
| 344 | + metadata: { |
| 345 | + customer_id: 'cust_test_id', |
| 346 | + subscription_id: 'sub_test_id' |
| 347 | + } |
| 348 | + }, |
| 349 | + success_url: |
| 350 | + 'http://localhost:8000/update-stripe-card?session_id={CHECKOUT_SESSION_ID}' |
| 351 | + }); |
| 352 | + expect(response.body).toEqual({ sessionId: 'checkout_session_id' }); |
| 353 | + expect(response.status).toBe(200); |
| 354 | + }); |
| 355 | + it('should return 500 if there is no donation record', async () => { |
| 356 | + const response = await superPut('/donate/update-stripe-card').send({}); |
| 357 | + expect(response.body).toEqual({ |
| 358 | + message: 'flash.generic-error', |
| 359 | + type: 'danger' |
| 360 | + }); |
| 361 | + expect(response.status).toBe(500); |
| 362 | + }); |
| 363 | + }); |
| 364 | + |
305 | 365 | describe('POST /donate/create-stripe-payment-intent', () => { |
306 | 366 | it('should return 200 and call stripe api properly', async () => { |
307 | 367 | mockSubCreate.mockImplementationOnce( |
@@ -432,16 +492,16 @@ describe('Donate', () => { |
432 | 492 | }); |
433 | 493 |
|
434 | 494 | describe('Unauthenticated User', () => { |
435 | | - let setCookies: string[]; |
436 | 495 | // Get the CSRF cookies from an unprotected route |
437 | 496 | beforeAll(async () => { |
438 | 497 | const res = await superRequest('/status/ping', { method: 'GET' }); |
439 | 498 | setCookies = res.get('Set-Cookie'); |
440 | 499 | }); |
441 | 500 |
|
442 | | - const endpoints: { path: string; method: 'POST' }[] = [ |
| 501 | + const endpoints: { path: string; method: 'POST' | 'PUT' }[] = [ |
443 | 502 | { path: '/donate/add-donation', method: 'POST' }, |
444 | | - { path: '/donate/charge-stripe-card', method: 'POST' } |
| 503 | + { path: '/donate/charge-stripe-card', method: 'POST' }, |
| 504 | + { path: '/donate/update-stripe-card', method: 'PUT' } |
445 | 505 | ]; |
446 | 506 |
|
447 | 507 | endpoints.forEach(({ path, method }) => { |
|
0 commit comments