Skip to content

Commit

Permalink
fix(stripe-payment): fix minor issue in stripe payment (#120)
Browse files Browse the repository at this point in the history
-  add status check on the stripe response before setting order.paid to true

[Fixes #119]
  • Loading branch information
jkarenzi authored Jun 3, 2024
1 parent 1bf5feb commit de5f934
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 95 deletions.
199 changes: 110 additions & 89 deletions src/__test__/payment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,97 +5,118 @@ import { Order } from '../database/models/orderEntity';
import dbConnection from '../database';
import Stripe from 'stripe';


jest.mock('stripe');
const MockedStripe = Stripe as jest.Mocked<typeof Stripe>;


describe('handlePayment', () => {
let token: string;
let order: Order;


beforeAll(async () => {
await dbConnection.initialize();
await dbConnection.synchronize(true); // This will drop all tables
token = await getBuyerToken();
// Create a mock order in the database
const orderRepository = dbConnection.getRepository(Order);
order = orderRepository.create({
totalAmount: 100,
status: 'Pending',
trackingNumber: '123456',
paid: false,
});
await orderRepository.save(order);
});


afterAll(async () => {
await dbConnection.close();
});


it('should process payment successfully', async () => {
const mockChargesCreate = jest.fn().mockResolvedValue({
id: 'charge_id',
amount: 10000,
currency: 'usd',
} as Stripe.Charge);


MockedStripe.prototype.charges = {
create: mockChargesCreate,
} as unknown as Stripe.ChargesResource;


const response = await request(app)
.post('/api/v1/buyer/payment')
.set('Authorization', `Bearer ${token}`)
.send({ token: 'fake-token', orderId: order.id });


expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(response.body.paid).toBe(true);
expect(response.body.charge.id).toBe('charge_id');
expect(mockChargesCreate).toHaveBeenCalledWith({
amount: 10000,
currency: 'usd',
description: 'Test Charge',
source: 'fake-token',
});
});


it('should return 404 if order not found', async () => {
const response = await request(app)
.post('/api/v1/buyer/payment')
.set('Authorization', `Bearer ${token}`)
.send({ token: 'fake-token', orderId: 999 });


expect(response.status).toBe(404);
expect(response.body.success).toBe(false);
expect(response.body.message).toBe('Order not found');
});


it('should return 400 if order already paid', async () => {
// Set the order as paid
const orderRepository = dbConnection.getRepository(Order);
order.paid = true;
await orderRepository.save(order);


const response = await request(app)
.post('/api/v1/buyer/payment')
.set('Authorization', `Bearer ${token}`)
.send({ token: 'fake-token', orderId: order.id });


expect(response.status).toBe(400);
expect(response.body.success).toBe(false);
expect(response.body.message).toBe('Order has already been paid');
});
let token: string;
let order: Order;

beforeAll(async () => {
await dbConnection.initialize();
await dbConnection.synchronize(true); // This will drop all tables
token = await getBuyerToken();
// Create a mock order in the database
const orderRepository = dbConnection.getRepository(Order);
order = orderRepository.create({
totalAmount: 100,
status: 'Pending',
trackingNumber: '123456',
paid: false,
});
await orderRepository.save(order);
});

afterAll(async () => {
await dbConnection.close();
});

it('should process payment successfully', async () => {
const mockChargesCreate = jest.fn().mockResolvedValue({
id: 'charge_id',
amount: 10000,
currency: 'usd',
status: 'succeeded',
} as Stripe.Charge);

MockedStripe.prototype.charges = {
create: mockChargesCreate,
} as unknown as Stripe.ChargesResource;

const response = await request(app)
.post('/api/v1/buyer/payment')
.set('Authorization', `Bearer ${token}`)
.send({ token: 'fake-token', orderId: order.id });

expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(response.body.paid).toBe(true);
expect(response.body.charge.id).toBe('charge_id');
expect(mockChargesCreate).toHaveBeenCalledWith({
amount: 10000,
currency: 'usd',
description: 'Test Charge',
source: 'fake-token',
});
});

it('should return 400 if payment is not successful', async () => {
// Set the order as not paid
const orderRepository = dbConnection.getRepository(Order);
order.paid = false;
await orderRepository.save(order);

const mockChargesCreate = jest.fn().mockResolvedValue({
id: 'charge_id',
amount: 10000,
currency: 'usd',
status: 'failed',
} as Stripe.Charge);

MockedStripe.prototype.charges = {
create: mockChargesCreate,
} as unknown as Stripe.ChargesResource;

const response = await request(app)
.post('/api/v1/buyer/payment')
.set('Authorization', `Bearer ${token}`)
.send({ token: 'fake-token', orderId: order.id });

expect(response.status).toBe(400);
expect(response.body.success).toBe(false);
expect(response.body.paid).toBe(false);
expect(mockChargesCreate).toHaveBeenCalledWith({
amount: 10000,
currency: 'usd',
description: 'Test Charge',
source: 'fake-token',
});
});

it('should return 404 if order not found', async () => {
const response = await request(app)
.post('/api/v1/buyer/payment')
.set('Authorization', `Bearer ${token}`)
.send({ token: 'fake-token', orderId: 999 });

expect(response.status).toBe(404);
expect(response.body.success).toBe(false);
expect(response.body.message).toBe('Order not found');
});

it('should return 400 if order already paid', async () => {
// Set the order as paid
const orderRepository = dbConnection.getRepository(Order);
order.paid = true;
await orderRepository.save(order);

const response = await request(app)
.post('/api/v1/buyer/payment')
.set('Authorization', `Bearer ${token}`)
.send({ token: 'fake-token', orderId: order.id });

expect(response.status).toBe(400);
expect(response.body.success).toBe(false);
expect(response.body.message).toBe('Order has already been paid');
});
});
17 changes: 11 additions & 6 deletions src/controller/buyerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,17 @@ export const getOneProduct = errorHandler(
description: 'Test Charge',
source: token,
});


order.paid = true;
await orderRepository.save(order);

return res.status(200).json({ success: true, paid: true, charge});

if (charge.status === 'succeeded') {
order.paid = true;
await orderRepository.save(order)

return res.status(200).json({ success: true, paid: true, charge});
}else{
return res
.status(400)
.json({ success: false, paid: false, message: `Charge status: ${charge.status}` });
}
}
);

0 comments on commit de5f934

Please sign in to comment.