Files
dbis_core-lite/tests/unit/services/message-service.test.ts
2026-02-09 21:51:45 -08:00

178 lines
6.1 KiB
TypeScript

import { MessageService } from '@/messaging/message-service';
import { MessageRepository } from '@/repositories/message-repository';
import { PaymentRepository } from '@/repositories/payment-repository';
import { PaymentTransaction, PaymentType, PaymentStatus } from '@/models/payment';
import { MessageType } from '@/models/message';
import { TestHelpers } from '../../utils/test-helpers';
describe('MessageService', () => {
let messageService: MessageService;
let messageRepository: MessageRepository;
let paymentRepository: PaymentRepository;
let testPayment: PaymentTransaction;
beforeAll(async () => {
messageRepository = new MessageRepository();
paymentRepository = new PaymentRepository();
messageService = new MessageService(messageRepository, paymentRepository);
});
beforeEach(async () => {
await TestHelpers.cleanDatabase();
// Create test payment with ledger transaction ID
const operator = await TestHelpers.createTestOperator('TEST_MSG_SVC', 'MAKER' as any);
const paymentRequest = TestHelpers.createTestPaymentRequest();
const paymentId = await paymentRepository.create(
paymentRequest,
operator.id,
`TEST-MSG-${Date.now()}`
);
const payment = await paymentRepository.findById(paymentId);
if (!payment) {
throw new Error('Failed to create test payment');
}
// Update payment with internal transaction ID (required for message generation)
await paymentRepository.update(paymentId, {
internalTransactionId: 'test-txn-123',
status: PaymentStatus.LEDGER_POSTED,
});
testPayment = (await paymentRepository.findById(paymentId))!;
});
afterAll(async () => {
await TestHelpers.cleanDatabase();
});
describe('generateMessage', () => {
it('should generate PACS.008 message for CUSTOMER_CREDIT_TRANSFER', async () => {
const payment: PaymentTransaction = {
...testPayment,
type: PaymentType.CUSTOMER_CREDIT_TRANSFER,
internalTransactionId: 'test-txn-001',
};
const result = await messageService.generateMessage(payment);
expect(result.messageId).toBeDefined();
expect(result.uetr).toBeDefined();
expect(result.msgId).toBeDefined();
expect(result.xml).toBeDefined();
expect(result.hash).toBeDefined();
expect(result.xml).toContain('pacs.008');
expect(result.xml).toContain('FIToFICstmrCdtTrf');
});
it('should generate PACS.009 message for FI_TO_FI', async () => {
const payment: PaymentTransaction = {
...testPayment,
type: PaymentType.FI_TO_FI,
internalTransactionId: 'test-txn-002',
};
const result = await messageService.generateMessage(payment);
expect(result.messageId).toBeDefined();
expect(result.uetr).toBeDefined();
expect(result.msgId).toBeDefined();
expect(result.xml).toBeDefined();
expect(result.xml).toContain('pacs.009');
expect(result.xml).toContain('FICdtTrf');
});
it('should fail if ledger posting not found', async () => {
const paymentWithoutLedger: PaymentTransaction = {
...testPayment,
internalTransactionId: undefined,
};
await expect(
messageService.generateMessage(paymentWithoutLedger)
).rejects.toThrow('Ledger posting not found');
});
it('should store message in repository', async () => {
const payment: PaymentTransaction = {
...testPayment,
internalTransactionId: 'test-txn-003',
};
const result = await messageService.generateMessage(payment);
const storedMessage = await messageRepository.findById(result.messageId);
expect(storedMessage).not.toBeNull();
expect(storedMessage?.messageType).toBe(MessageType.PACS_008);
expect(storedMessage?.uetr).toBe(result.uetr);
expect(storedMessage?.xmlContent).toBe(result.xml);
});
it('should update payment with message information', async () => {
const payment: PaymentTransaction = {
...testPayment,
internalTransactionId: 'test-txn-004',
};
const result = await messageService.generateMessage(payment);
const updatedPayment = await paymentRepository.findById(payment.id);
expect(updatedPayment?.uetr).toBe(result.uetr);
expect(updatedPayment?.isoMessageId).toBe(result.messageId);
expect(updatedPayment?.isoMessageHash).toBe(result.hash);
});
});
describe('getMessage', () => {
it('should retrieve message by ID', async () => {
const payment: PaymentTransaction = {
...testPayment,
internalTransactionId: 'test-txn-005',
};
const generated = await messageService.generateMessage(payment);
const retrieved = await messageService.getMessage(generated.messageId);
expect(retrieved).not.toBeNull();
expect(retrieved?.id).toBe(generated.messageId);
expect(retrieved?.xmlContent).toBe(generated.xml);
});
it('should return null for non-existent message', async () => {
const message = await messageService.getMessage('non-existent-id');
expect(message).toBeNull();
});
});
describe('getMessageByPaymentId', () => {
it('should retrieve message by payment ID', async () => {
const payment: PaymentTransaction = {
...testPayment,
internalTransactionId: 'test-txn-006',
};
const generated = await messageService.generateMessage(payment);
const retrieved = await messageService.getMessageByPaymentId(payment.id);
expect(retrieved).not.toBeNull();
expect(retrieved?.paymentId).toBe(payment.id);
expect(retrieved?.id).toBe(generated.messageId);
});
it('should return null if no message exists for payment', async () => {
const operator = await TestHelpers.createTestOperator('TEST_NOMSG', 'MAKER' as any);
const paymentRequest = TestHelpers.createTestPaymentRequest();
const paymentId = await paymentRepository.create(
paymentRequest,
operator.id,
`TEST-NOMSG-${Date.now()}`
);
const message = await messageService.getMessageByPaymentId(paymentId);
expect(message).toBeNull();
});
});
});