133 lines
3.7 KiB
JavaScript
133 lines
3.7 KiB
JavaScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import mockRequire from "mock-require";
|
|
|
|
const gqlRequestMock = { request: vi.fn() };
|
|
const getPaymentTypeMock = vi.fn(() => "Visa");
|
|
const handlePaymentValidationErrorMock = vi.fn();
|
|
|
|
let handleInvoiceBasedPayment;
|
|
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.clearAllMocks();
|
|
|
|
mockRequire("../../../graphql-client/graphql-client", {
|
|
client: gqlRequestMock
|
|
});
|
|
|
|
mockRequire("../getPaymentType", getPaymentTypeMock);
|
|
mockRequire("../handlePaymentValidationError", handlePaymentValidationErrorMock);
|
|
|
|
handleInvoiceBasedPayment = require("../handleInvoiceBasedPayment");
|
|
|
|
gqlRequestMock.request
|
|
.mockResolvedValueOnce({
|
|
jobs: [
|
|
{
|
|
id: "job123",
|
|
bodyshop: {
|
|
id: "shop123",
|
|
intellipay_config: {
|
|
payment_map: {
|
|
visa: "Visa"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
})
|
|
.mockResolvedValueOnce({
|
|
insert_payments: {
|
|
returning: [{ id: "payment123" }]
|
|
}
|
|
})
|
|
.mockResolvedValueOnce({
|
|
insert_payment_response: {
|
|
returning: [{ id: "response123" }]
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("handleInvoiceBasedPayment", () => {
|
|
const mockLogger = { log: vi.fn() };
|
|
const mockRes = { sendStatus: vi.fn() };
|
|
|
|
const values = {
|
|
merchantid: "m123",
|
|
invoice: "INV-001",
|
|
total: 100.0,
|
|
authcode: "AUTH123",
|
|
cardtype: "visa",
|
|
paymentid: "P789"
|
|
};
|
|
|
|
const logMeta = { op: "abc123" };
|
|
|
|
it("processes a valid invoice-based payment", async () => {
|
|
await handleInvoiceBasedPayment(values, mockLogger, logMeta, mockRes);
|
|
|
|
expect(gqlRequestMock.request).toHaveBeenCalledTimes(3);
|
|
expect(getPaymentTypeMock).toHaveBeenCalledWith({ visa: "Visa" }, "visa");
|
|
expect(mockRes.sendStatus).toHaveBeenCalledWith(200);
|
|
expect(handlePaymentValidationErrorMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("handles missing merchantid with validation error", async () => {
|
|
const invalidValues = { ...values, merchantid: undefined };
|
|
|
|
await handleInvoiceBasedPayment(invalidValues, mockLogger, logMeta, mockRes);
|
|
|
|
expect(handlePaymentValidationErrorMock).toHaveBeenCalledWith(
|
|
mockRes,
|
|
mockLogger,
|
|
"intellipay-postback-no-merchantid",
|
|
"Merchant ID is missing",
|
|
logMeta
|
|
);
|
|
expect(gqlRequestMock.request).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("handles job not found with validation error", async () => {
|
|
gqlRequestMock.request.mockReset();
|
|
gqlRequestMock.request.mockResolvedValueOnce({ jobs: [] });
|
|
|
|
await handleInvoiceBasedPayment(values, mockLogger, logMeta, mockRes);
|
|
|
|
expect(handlePaymentValidationErrorMock).toHaveBeenCalledWith(
|
|
mockRes,
|
|
mockLogger,
|
|
"intellipay-postback-job-not-found",
|
|
"Job not found",
|
|
logMeta,
|
|
200
|
|
);
|
|
});
|
|
|
|
it("handles missing bodyshop with validation error", async () => {
|
|
gqlRequestMock.request.mockReset();
|
|
gqlRequestMock.request.mockResolvedValueOnce({
|
|
jobs: [{ id: "job123", bodyshop: null }]
|
|
});
|
|
|
|
await handleInvoiceBasedPayment(values, mockLogger, logMeta, mockRes);
|
|
|
|
expect(handlePaymentValidationErrorMock).toHaveBeenCalledWith(
|
|
mockRes,
|
|
mockLogger,
|
|
"intellipay-postback-bodyshop-not-found",
|
|
"Bodyshop not found",
|
|
logMeta
|
|
);
|
|
});
|
|
|
|
it("logs all expected stages of the process", async () => {
|
|
await handleInvoiceBasedPayment(values, mockLogger, logMeta, mockRes);
|
|
|
|
const logTags = mockLogger.log.mock.calls.map(([tag]) => tag);
|
|
|
|
expect(logTags).toContain("intellipay-postback-invoice-job-fetched");
|
|
expect(logTags).toContain("intellipay-postback-invoice-payment-success");
|
|
expect(logTags).toContain("intellipay-postback-invoice-response-success");
|
|
});
|
|
});
|