import { read, readSid } from "./read";
import { EnoFactory } from "./EnoFactory";
import { IEnSrvOptions } from "./IEnSrvOptions";
import * as Pull from "./pull";
import { firstValueFrom, of } from "rxjs";

const testEnSrvOptions: IEnSrvOptions = {
  enSrvUrl: "http://example.com",
  namespace: "myNameSpace",
};

describe("read", () => {
  it("Should read an eno by tip", async () => {
    const enoFactory = new EnoFactory("mytype");
    enoFactory.setSecurity("security/policy/local");
    const eno = enoFactory.makeEno();

    const pullSpy = spyOn(Pull, "pull").and.returnValue(of([eno]));
    const pullOptions = {};

    const responseEno = await firstValueFrom(
      read(eno.tip, testEnSrvOptions, pullOptions)
    );

    expect(responseEno.tip).toBe(eno.tip);
    expect(pullSpy).toHaveBeenCalledWith(
      [eno.tip],
      testEnSrvOptions,
      pullOptions
    );
  });

  it("Should read an eno by sid", async () => {
    const enoFactory = new EnoFactory("mytype");
    enoFactory.setSecurity("security/policy/local");
    const eno = enoFactory.makeEno();

    const pullSidSpy = spyOn(Pull, "pullSid").and.returnValue(of([eno]));
    const pullOptions = {};

    const responseEno = await firstValueFrom(
      readSid(eno.sid, testEnSrvOptions, pullOptions)
    );

    expect(responseEno.sid).toBe(eno.sid);
    expect(pullSidSpy).toHaveBeenCalledWith(
      [eno.sid],
      testEnSrvOptions,
      pullOptions
    );
  });

  it("Should error when not found", (done) => {
    const enoFactory = new EnoFactory("error");
    enoFactory.setSecurity("security/policy/local");
    enoFactory.setField("error/message/tip", ["error/message/eno/not-found"]);
    const eno = enoFactory.makeEno();

    spyOn(Pull, "pull").and.returnValue(of([eno]));

    read("test-tip", testEnSrvOptions).subscribe({
      next: (_) => {
        throw "Should not have found eno";
      },
      error: (err) => {
        expect(err.message).toBe("error/message/eno/not-found");
        done();
      },
    });
  });

  it("Should error when response empty", (done) => {
    spyOn(Pull, "pull").and.returnValue(of([]));

    read("test-tip", testEnSrvOptions).subscribe({
      next: (_) => {
        throw "Should not have found eno";
      },
      error: (err) => {
        expect(err.message).toBe("error/message/eno/not-found");
        done();
      },
    });
  });
});
