import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; const { mockSend } = vi.hoisted(() => ({ mockSend: vi.fn() })); vi.mock("@aws-sdk/client-secrets-manager", () => { return { SecretsManagerClient: vi.fn(() => ({ send: mockSend })), GetSecretValueCommand: vi.fn((input) => input) }; }); const getPaymentType = require("../getPaymentType"); const decodeComment = require("../decodeComment"); const getCptellerUrl = require("../getCptellerUrl"); const handlePaymentValidationError = require("../handlePaymentValidationError"); const getShopCredentials = require("../getShopCredentials"); describe("Payment Processing Functions", () => { // DecodeComment Tests describe("decodeComment", () => { it("decodes a valid base64-encoded JSON comment", () => { const encoded = "eyJ0ZXN0IjoiZGF0YSJ9"; const expected = { test: "data" }; expect(decodeComment(encoded)).toEqual(expected); }); it("decodes a complex base64-encoded JSON with payments", () => { const encoded = "eyJwYXltZW50cyI6W3siam9iaWQiOiIxMjMifV19"; const expected = { payments: [{ jobid: "123" }] }; expect(decodeComment(encoded)).toEqual(expected); }); it("returns null when comment is null", () => { expect(decodeComment(null)).toBeNull(); }); it("returns null when comment is undefined", () => { expect(decodeComment(undefined)).toBeNull(); }); it("returns null when comment is an empty string", () => { expect(decodeComment("")).toBeNull(); }); it("returns null when comment is malformed base64", () => { expect(decodeComment("!@#$%")).toBeNull(); }); it("returns null when comment is valid base64 but not valid JSON", () => { expect(decodeComment("aW52YWxpZA==")).toBeNull(); }); }); // GetPaymentType Tests describe("getPaymentType", () => { it("returns mapped value when card type exists in mapping", () => { const ipMapping = { visa: "Visa Card", amex: "American Express" }; expect(getPaymentType(ipMapping, "visa")).toBe("Visa Card"); }); it("returns original value when card type not in mapping", () => { const ipMapping = { visa: "Visa Card" }; expect(getPaymentType(ipMapping, "mastercard")).toBe("mastercard"); }); it("handles lowercase conversion", () => { const ipMapping = { visa: "Visa Card" }; expect(getPaymentType(ipMapping, "VISA")).toBe("Visa Card"); }); it("handles null mapping", () => { expect(getPaymentType(null, "visa")).toBe("visa"); }); it("handles undefined mapping", () => { expect(getPaymentType(undefined, "visa")).toBe("visa"); }); it("handles empty string card type", () => { const ipMapping = { visa: "Visa Card" }; expect(getPaymentType(ipMapping, "")).toBe(""); }); it("handles undefined card type", () => { const ipMapping = { visa: "Visa Card" }; expect(getPaymentType(ipMapping, undefined)).toBe(undefined); }); }); // GetCptellerUrl Tests describe("getCptellerUrl", () => { const originalEnv = process.env.NODE_ENV; afterEach(() => { process.env.NODE_ENV = originalEnv; }); it("uses test domain in non-production environment", () => { process.env.NODE_ENV = ""; const url = getCptellerUrl({ apiType: "webapi" }); expect(url).toEqual("https://test.cpteller.com/api/webapi.cfc"); }); it("uses secure domain in production environment", () => { process.env.NODE_ENV = "production"; const url = getCptellerUrl({ apiType: "webapi" }); expect(url).toEqual("https://secure.cpteller.com/api/webapi.cfc"); }); it("adds version number for webapi type", () => { process.env.NODE_ENV = ""; const url = getCptellerUrl({ apiType: "webapi", version: "26" }); expect(url).toEqual("https://test.cpteller.com/api/26/webapi.cfc"); }); it("constructs custapi URL without version number", () => { process.env.NODE_ENV = ""; const url = getCptellerUrl({ apiType: "custapi", version: "26" }); expect(url).toEqual("https://test.cpteller.com/api/custapi.cfc"); }); it("adds query parameters to the URL", () => { process.env.NODE_ENV = ""; const url = getCptellerUrl({ apiType: "webapi", params: { method: "payment_refund", test: "value" } }); expect(url).toEqual("https://test.cpteller.com/api/webapi.cfc?method=payment_refund&test=value"); }); it("handles empty params object", () => { process.env.NODE_ENV = ""; const url = getCptellerUrl({ apiType: "webapi", params: {} }); expect(url).toEqual("https://test.cpteller.com/api/webapi.cfc"); }); it("defaults to webapi when no apiType is provided", () => { process.env.NODE_ENV = ""; const url = getCptellerUrl({}); expect(url).toEqual("https://test.cpteller.com/api/webapi.cfc"); }); it("combines version and query parameters correctly", () => { process.env.NODE_ENV = ""; const url = getCptellerUrl({ apiType: "webapi", version: "26", params: { method: "fee" } }); expect(url).toEqual("https://test.cpteller.com/api/26/webapi.cfc?method=fee"); }); }); // GetShopCredentials Tests describe("getShopCredentials", () => { const originalEnv = { ...process.env }; beforeEach(() => { mockSend.mockReset(); process.env.INTELLIPAY_MERCHANTKEY = "test-merchant-key"; process.env.INTELLIPAY_APIKEY = "test-api-key"; }); afterEach(() => { process.env = { ...originalEnv }; }); it("returns environment variables in non-production environment", async () => { process.env.NODE_ENV = "development"; const result = await getShopCredentials({ imexshopid: "12345" }); expect(result).toEqual({ merchantkey: "test-merchant-key", apikey: "test-api-key" }); expect(mockSend).not.toHaveBeenCalled(); }); it("returns undefined when imexshopid is missing in production", async () => { process.env.NODE_ENV = "production"; const result = await getShopCredentials({ name: "Test Shop" }); expect(result).toBeUndefined(); expect(mockSend).not.toHaveBeenCalled(); }); it("returns undefined for null bodyshop in production", async () => { process.env.NODE_ENV = "production"; const result = await getShopCredentials(null); expect(result).toBeUndefined(); expect(mockSend).not.toHaveBeenCalled(); }); it("returns undefined for undefined bodyshop in production", async () => { process.env.NODE_ENV = "production"; const result = await getShopCredentials(undefined); expect(result).toBeUndefined(); expect(mockSend).not.toHaveBeenCalled(); }); }); // HandlePaymentValidationError Tests describe("handlePaymentValidationError", () => { it("logs error and sends 400 response", () => { const mockLog = vi.fn(); const mockLogger = { log: mockLog }; const mockRes = { status: vi.fn().mockReturnThis(), send: vi.fn().mockReturnThis() }; const logCode = "test-validation-error"; const message = "Invalid data"; const logMeta = { field: "test", value: 123 }; const result = handlePaymentValidationError(mockRes, mockLogger, logCode, message, logMeta); expect(mockLog).toHaveBeenCalledWith(logCode, "ERROR", "api", null, { message, ...logMeta }); expect(mockRes.status).toHaveBeenCalledWith(400); expect(mockRes.send).toHaveBeenCalledWith(`Bad Request: ${message}`); expect(result).toBe(mockRes); }); it("formats different error messages correctly", () => { const mockLog = vi.fn(); const mockLogger = { log: mockLog }; const mockRes = { status: vi.fn().mockReturnThis(), send: vi.fn().mockReturnThis() }; handlePaymentValidationError(mockRes, mockLogger, "error-code", "Custom error"); expect(mockRes.send).toHaveBeenCalledWith("Bad Request: Custom error"); }); it("passes different logCodes to logger", () => { const mockLog = vi.fn(); const mockLogger = { log: mockLog }; const mockRes = { status: vi.fn().mockReturnThis(), send: vi.fn().mockReturnThis() }; handlePaymentValidationError(mockRes, mockLogger, "custom-log-code", "Error message"); expect(mockLog).toHaveBeenCalledWith("custom-log-code", "ERROR", "api", null, { message: "Error message" }); }); it("works with minimal logMeta", () => { const mockLog = vi.fn(); const mockLogger = { log: mockLog }; const mockRes = { status: vi.fn().mockReturnThis(), send: vi.fn().mockReturnThis() }; handlePaymentValidationError(mockRes, mockLogger, "error-code", "Error message", {}); expect(mockLog).toHaveBeenCalledWith("error-code", "ERROR", "api", null, { message: "Error message" }); }); it("works with undefined logMeta", () => { const mockLog = vi.fn(); const mockLogger = { log: mockLog }; const mockRes = { status: vi.fn().mockReturnThis(), send: vi.fn().mockReturnThis() }; handlePaymentValidationError(mockRes, mockLogger, "error-code", "Error message"); expect(mockLog).toHaveBeenCalledWith("error-code", "ERROR", "api", null, { message: "Error message" }); }); }); });