153 lines
4.7 KiB
JavaScript
153 lines
4.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(() => "American Express");
|
|
const sendPaymentNotificationEmailMock = vi.fn();
|
|
|
|
let handleCommentBasedPayment;
|
|
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.clearAllMocks();
|
|
|
|
// Mock dependencies using mock-require BEFORE requiring the target module
|
|
mockRequire("../../../graphql-client/graphql-client", {
|
|
client: gqlRequestMock
|
|
});
|
|
|
|
mockRequire("../getPaymentType", getPaymentTypeMock);
|
|
mockRequire("../sendPaymentNotificationEmail", sendPaymentNotificationEmailMock);
|
|
|
|
// Now require the module under test
|
|
handleCommentBasedPayment = require("../handleCommentBasedPayment");
|
|
|
|
// Chain your GraphQL mocks
|
|
gqlRequestMock.request
|
|
.mockResolvedValueOnce({
|
|
jobs: [
|
|
{
|
|
id: "c1ffe09c-e7d4-46b3-aac5-f23e39563181",
|
|
shopid: "bfec8c8c-b7f1-49e0-be4c-524455f4e582"
|
|
}
|
|
]
|
|
})
|
|
.mockResolvedValueOnce({
|
|
bodyshops_by_pk: {
|
|
id: "bfec8c8c-b7f1-49e0-be4c-524455f4e582",
|
|
intellipay_config: {
|
|
payment_map: {
|
|
amex: "American Express"
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.mockResolvedValueOnce({
|
|
insert_payments: {
|
|
returning: [{ id: "5dfda3c4-c0a6-4b09-a73d-176ed0ac6499" }]
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("handleCommentBasedPayment", () => {
|
|
const mockLogger = { log: vi.fn() };
|
|
const mockRes = { sendStatus: vi.fn() };
|
|
|
|
const values = {
|
|
authcode: "5557301",
|
|
total: "0.01",
|
|
origin: "Dejavoo",
|
|
paymentid: "24294378",
|
|
cardtype: "Amex"
|
|
};
|
|
|
|
const decodedComment = {
|
|
payments: [{ jobid: "c1ffe09c-e7d4-46b3-aac5-f23e39563181", amount: 0.01 }],
|
|
userEmail: "test@example.com"
|
|
};
|
|
|
|
const logMeta = { op: "xyz123" };
|
|
|
|
it("processes comment-based payment and returns 200", async () => {
|
|
await handleCommentBasedPayment(values, decodedComment, mockLogger, logMeta, mockRes);
|
|
|
|
expect(gqlRequestMock.request).toHaveBeenCalledTimes(3);
|
|
expect(getPaymentTypeMock).toHaveBeenCalledWith({ amex: "American Express" }, "Amex");
|
|
expect(sendPaymentNotificationEmailMock).not.toHaveBeenCalled();
|
|
expect(mockRes.sendStatus).toHaveBeenCalledWith(200);
|
|
});
|
|
|
|
it("sends notification if origin is OneLink and userEmail exists", async () => {
|
|
const oneLinkValues = { ...values, origin: "OneLink" };
|
|
|
|
await handleCommentBasedPayment(oneLinkValues, decodedComment, mockLogger, logMeta, mockRes);
|
|
|
|
expect(sendPaymentNotificationEmailMock).toHaveBeenCalledWith(
|
|
"test@example.com",
|
|
expect.anything(),
|
|
expect.anything(),
|
|
mockLogger,
|
|
logMeta
|
|
);
|
|
|
|
expect(mockRes.sendStatus).toHaveBeenCalledWith(200);
|
|
});
|
|
|
|
it("handles decodedComment as a direct array", async () => {
|
|
const arrayComment = [{ jobid: "c1ffe09c-e7d4-46b3-aac5-f23e39563181", amount: 0.01 }];
|
|
|
|
await handleCommentBasedPayment(values, arrayComment, mockLogger, logMeta, mockRes);
|
|
|
|
expect(gqlRequestMock.request).toHaveBeenCalledTimes(3);
|
|
expect(mockRes.sendStatus).toHaveBeenCalledWith(200);
|
|
});
|
|
|
|
it("does not send email if origin is OneLink but userEmail is missing", async () => {
|
|
const commentWithoutEmail = {
|
|
payments: decodedComment.payments
|
|
// no userEmail
|
|
};
|
|
|
|
const oneLinkValues = { ...values, origin: "OneLink" };
|
|
|
|
await handleCommentBasedPayment(oneLinkValues, commentWithoutEmail, mockLogger, logMeta, mockRes);
|
|
|
|
expect(sendPaymentNotificationEmailMock).not.toHaveBeenCalled();
|
|
expect(mockRes.sendStatus).toHaveBeenCalledWith(200);
|
|
});
|
|
|
|
it("logs important stages of the process", async () => {
|
|
await handleCommentBasedPayment(values, decodedComment, mockLogger, logMeta, mockRes);
|
|
|
|
const logCalls = mockLogger.log.mock.calls.map(([tag]) => tag);
|
|
|
|
expect(logCalls).toContain("intellipay-postback-parsed-comment");
|
|
expect(logCalls).toContain("intellipay-postback-payment-success");
|
|
});
|
|
|
|
it("handles missing payment_map safely", async () => {
|
|
gqlRequestMock.request.mockReset(); // 🧹 Clear previous .mockResolvedValueOnce calls
|
|
|
|
gqlRequestMock.request
|
|
.mockResolvedValueOnce({
|
|
jobs: [{ id: "job1", shopid: "shop1" }]
|
|
})
|
|
.mockResolvedValueOnce({
|
|
bodyshops_by_pk: {
|
|
id: "shop1",
|
|
intellipay_config: null
|
|
}
|
|
})
|
|
.mockResolvedValueOnce({
|
|
insert_payments: {
|
|
returning: [{ id: "payment1" }]
|
|
}
|
|
});
|
|
|
|
await handleCommentBasedPayment(values, decodedComment, mockLogger, logMeta, mockRes);
|
|
|
|
expect(getPaymentTypeMock).toHaveBeenCalledWith(undefined, "Amex");
|
|
expect(mockRes.sendStatus).toHaveBeenCalledWith(200);
|
|
});
|
|
});
|