94 lines
4.3 KiB
JavaScript
94 lines
4.3 KiB
JavaScript
const mockPaymentFindOne = jest.fn();
|
|
const mockOrderFindByPk = jest.fn();
|
|
const mockOrderFindOne = jest.fn();
|
|
|
|
jest.mock('../../../../models/migration', () => ({
|
|
Payment: { findOne: mockPaymentFindOne, update: jest.fn() },
|
|
Order: { findByPk: mockOrderFindByPk, findOne: mockOrderFindOne, update: jest.fn() }
|
|
}));
|
|
|
|
jest.mock('../../models/migration', () => ({
|
|
Payment: { findOne: mockPaymentFindOne, update: jest.fn() },
|
|
Order: { findByPk: mockOrderFindByPk, findOne: mockOrderFindOne, update: jest.fn() }
|
|
}));
|
|
|
|
const notificationService = require('../../app/modules/notification/services/notification.service');
|
|
const crypto = require('crypto');
|
|
|
|
describe('NotificationService', () => {
|
|
const serverKey = 'SB-Mid-server-test';
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
process.env.MIDTRANS_SERVER_KEY = serverKey;
|
|
});
|
|
|
|
describe('verifySignature', () => {
|
|
it('should return true for a valid signature', () => {
|
|
const payload = { order_id: 'I-123', status_code: '200', gross_amount: '10.00', signature_key: '' };
|
|
const data = payload.order_id + payload.status_code + payload.gross_amount + serverKey;
|
|
payload.signature_key = crypto.createHash('sha512').update(data).digest('hex');
|
|
expect(notificationService.verifySignature(payload)).toBe(true);
|
|
});
|
|
|
|
it('should return false for invalid signature', () => {
|
|
const payload = { order_id: 'I-123', status_code: '200', gross_amount: '10.00', signature_key: 'wrong' };
|
|
expect(notificationService.verifySignature(payload)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('processNotification', () => {
|
|
it('should update order to COMPLETED on settlement', async () => {
|
|
const payload = { order_id: 'I-123', transaction_status: 'settlement', fraud_status: 'accept' };
|
|
const mockUpdateOrder = jest.fn();
|
|
const mockUpdatePayment = jest.fn();
|
|
const mockPayment = { order_id: 'u-123', update: mockUpdatePayment };
|
|
const mockOrder = { id: 'u-123', status: 'PENDING', payment_status: 'PENDING', update: mockUpdateOrder };
|
|
|
|
mockPaymentFindOne.mockResolvedValue(mockPayment);
|
|
mockOrderFindByPk.mockResolvedValue(mockOrder);
|
|
|
|
await notificationService.processNotification(payload);
|
|
expect(mockUpdateOrder).toHaveBeenCalledWith(expect.objectContaining({ status: 'COMPLETED', payment_status: 'PAID' }));
|
|
expect(mockUpdatePayment).toHaveBeenCalledWith(expect.objectContaining({ status: 'SUCCESS' }));
|
|
});
|
|
|
|
it('should update order to FAILED on deny/cancel/expire', async () => {
|
|
const payload = { order_id: 'I-123', transaction_status: 'expire' };
|
|
const mockUpdate = jest.fn();
|
|
const mockOrder = { id: 'u-123', status: 'PENDING', update: mockUpdate };
|
|
|
|
mockPaymentFindOne.mockResolvedValue(null);
|
|
mockOrderFindOne.mockResolvedValue(mockOrder);
|
|
|
|
await notificationService.processNotification(payload);
|
|
expect(mockUpdate).toHaveBeenCalledWith(expect.objectContaining({ status: 'FAILED', payment_status: 'REJECT' }));
|
|
});
|
|
|
|
it('should update to PENDING on pending status', async () => {
|
|
const payload = { order_id: 'I-123', transaction_status: 'pending' };
|
|
const mockUpdate = jest.fn();
|
|
const mockOrder = { id: 'u-123', status: 'PENDING', payment_status: 'PENDING', update: mockUpdate };
|
|
|
|
mockPaymentFindOne.mockResolvedValue(null);
|
|
mockOrderFindOne.mockResolvedValue(mockOrder);
|
|
|
|
await notificationService.processNotification(payload);
|
|
// If already pending, it should skip update
|
|
expect(mockUpdate).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should warn if order not found', async () => {
|
|
const payload = { order_id: 'unknown' };
|
|
mockPaymentFindOne.mockResolvedValue(null);
|
|
mockOrderFindOne.mockResolvedValue(null);
|
|
mockOrderFindByPk.mockResolvedValue(null);
|
|
|
|
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
|
|
await notificationService.processNotification(payload);
|
|
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('tidak ditemukan'));
|
|
consoleSpy.mockRestore();
|
|
});
|
|
});
|
|
});
|