import { expect } from "chai";
import { LambdaInvoker } from "../resolvers/invokers/LambdaInvoker";
import { WorkflowInvoker } from "../resolvers/invokers/WorkflowInvoker";
import { mockLambdaInvocation } from "./helpers";

describe("LambdaInvoker", () => {
  let invoker: LambdaInvoker;

  beforeEach(() => {
    invoker = new LambdaInvoker("foo", "test", {
      properties: {
        name: { type: "string" },
      },
      required: ["name"],
    });
  });

  describe("execute", () => {
    it("should make request", async () => {
      const scope = mockLambdaInvocation("foo", "test");
      await invoker.execute({ name: "works" });
      expect(scope.isDone()).to.be.true;
    });

    it("should return results", async () => {
      mockLambdaInvocation("foo", "test", { result: true });
      const res = await invoker.execute({ name: "works" });
      expect(res).to.deep.equal({ result: true });
    });

    it("should send correct invocation input", async () => {
      const scope = mockLambdaInvocation(
        "foo",
        "test",
        { result: true },
        { name: "works" },
      );
      await invoker.execute({ name: "works" });
      expect(scope.isDone()).to.be.true;
    });

    it("should throw argument validation errors", async () => {
      let error: Error;
      await invoker.execute({ invalid: "works" }).catch((err) => (error = err));
      expect(error).to.not.be.undefined;
      expect(error.message).to.contain('requires property "name"');
    });
  });
});

describe("WorkflowInvoker", () => {
  let invoker: WorkflowInvoker;

  beforeEach(() => {
    invoker = new WorkflowInvoker("foo", {
      properties: {
        name: { type: "string" },
      },
      required: ["name"],
    });
  });

  describe("execute", () => {
    it("should make request", async () => {
      const scope = mockLambdaInvocation("workflow", "execute");
      await invoker.execute({ name: "works" });
      expect(scope.isDone()).to.be.true;
    });

    it.skip("should return results", async () => {
      mockLambdaInvocation("workflow", "execute", { result: true });
      const res = await invoker.execute({ name: "works" });
      expect(res).to.deep.equal({ result: true });
    });

    it.skip("should send correct invocation input", async () => {
      const scope = mockLambdaInvocation(
        "workflow",
        "execute",
        { result: true },
        {
          name: "foo",
          input: { name: "works" },
        },
      );
      await invoker.execute({ name: "works" });
      expect(scope.isDone()).to.be.true;
    });
  });
});
