/**
 * @jest-environment jsdom
 */
import CfCore from "../../../core/CfCore";

import Payments from "..";
import { CurrencyCode } from "../../../core/commonTypes";
import { PaymentAction, PaymentMethod } from "../typings";

import { PaymentsTypes } from "../typings";
import { ContentBlock } from "../../Navigation/typings";

let mockSender;
let mockImpressionManager = {};

describe("Payments", () => {
  beforeAll(() => {
    mockSender = {
      add() {
        return false;
      },
    };
  });

  afterEach(() => {
    // to remove the singleton instance
    (CfCore as any).instance = null;
  });

  it('Should deliver an "DeferredPayment" event with payment mechanism', async () => {
    const senderSpy = jest.spyOn(mockSender, "add");
    CfCore.createInstance(
      mockSender as any,
      mockImpressionManager as any,
      false,
      ContentBlock.Core,
      "device-id",
      false
    );

    const event = {
      id: "134",
      order_id: "1234",
      action: PaymentAction.PaymentProcessed,
      account_balance: -5,
      payment_amount: 100,
      currency: CurrencyCode.EUR,
      type: PaymentMethod.Credit,
      is_successful: true,
    };

    await Payments.logDeferredPaymentEvent(event);

    expect(senderSpy).toBeCalledWith(
      expect.anything(),
      expect.anything(),
      expect.objectContaining({
        type: PaymentsTypes.DeferredPayment,
        props: { ...event },
      }),
      expect.anything()
    );
  });

  it('Should deliver an "DeferredPayment" event with default payment mechanism', async () => {
    const senderSpy = jest.spyOn(mockSender, "add");
    CfCore.createInstance(
      mockSender as any,
      mockImpressionManager as any,
      false,
      ContentBlock.Core,
      "device-id",
      false
    );

    const event = {
      id: "134",
      order_id: "1234",
      action: PaymentAction.PaymentProcessed,
      account_balance: -5,
      payment_amount: 100,
      currency: CurrencyCode.EUR,
      is_successful: true,
    };

    const publicEvent = {
      ...event,
      type: PaymentMethod.BankTransfer,
    };

    await Payments.logDeferredPaymentEvent(event);

    expect(senderSpy).toBeCalledWith(
      expect.anything(),
      expect.anything(),
      expect.objectContaining({
        type: PaymentsTypes.DeferredPayment,
        props: { ...publicEvent },
      }),
      expect.anything()
    );
  });

  it('Should deliver an "PaymentMethod"', async () => {
    const senderSpy = jest.spyOn(mockSender, "add");
    CfCore.createInstance(
      mockSender as any,
      mockImpressionManager as any,
      false,
      ContentBlock.Core,
      "device-id",
      false
    );

    const event = {
      order_id: "123",
      type: PaymentMethod.BankCard,
      payment_amount: 123,
      currency: CurrencyCode.AED,
    };

    await Payments.logPaymentMethodEvent(event);

    expect(senderSpy).toBeCalledWith(
      expect.anything(),
      expect.anything(),
      expect.objectContaining({
        type: PaymentsTypes.PaymentMethod,
        props: { ...event },
      }),
      expect.anything()
    );
  });
});
