import { mock } from "jest-mock-extended";

import { ForwarderContext } from "../engine";

import { SimpleLogin, SimpleLoginSettings } from "./simple-login";

describe("Addy.io forwarder", () => {
  const context = mock<ForwarderContext<SimpleLoginSettings>>();

  afterEach(() => {
    jest.resetAllMocks();
  });

  describe("authenticate", () => {
    it("returns a bearer header with the token", () => {
      context.authenticationToken.mockReturnValue("token");

      const result = SimpleLogin.authenticate(null, context);

      expect(result).toEqual({ Authentication: "token" });
      expect(context.authenticationToken).toHaveBeenCalled();
    });
  });

  describe("settings", () => {
    it("should pass through deserialization", () => {
      const value: any = {};
      const result = SimpleLogin.forwarder.settings.deserializer(value);
      expect(result).toBe(value);
    });
  });

  describe("importBuffer", () => {
    it("should pass through deserialization", () => {
      const value: any = {};
      const result = SimpleLogin.forwarder.importBuffer.options.deserializer(value);
      expect(result).toBe(value);
    });
  });

  describe("createForwardingEmail", () => {
    describe("url", () => {
      it("returns the alias path", () => {
        context.website.mockReturnValue("");
        context.baseUrl.mockReturnValue("");

        const result = SimpleLogin.forwarder.createForwardingEmail.url(null, context);

        expect(result).toEqual("/api/alias/random/new");
      });

      it("includes the website in the alias path", () => {
        context.baseUrl.mockReturnValue("");
        context.website.mockReturnValue("website");

        const result = SimpleLogin.forwarder.createForwardingEmail.url(null, context);

        expect(result).toEqual("/api/alias/random/new?hostname=website");
      });
    });

    describe("body", () => {
      it("returns the alias path", () => {
        context.generatedBy.mockReturnValue("generated by");

        const result = SimpleLogin.forwarder.createForwardingEmail.body(null, context);

        expect(result).toEqual({
          note: "generated by",
        });
      });
    });

    describe("hasJsonPayload", () => {
      it.each([[200], [201]])("returns true when the status is $%i", (status) => {
        const result = SimpleLogin.forwarder.createForwardingEmail.hasJsonPayload(
          { status } as Response,
          context,
        );
        expect(result).toBeTruthy();
      });
    });

    describe("processJson", () => {
      it("should read the email from the response", () => {
        const json = { alias: "foo@example.com" };
        const result = SimpleLogin.forwarder.createForwardingEmail.processJson(json, context);
        expect(result).toEqual(["foo@example.com"]);
      });
    });
  });
});
