jest.mock("../../logger", () => ({
  reactHooksLogger: {
    warning: jest.fn(),
    addSubsystem: jest.fn(),
  },
}));

const {
  getInflatedDataSourceUrl,
  getSearchContext,
} = require("../useInflatedUrl");

const { reactHooksLogger } = require("../../logger");

let mockStore;

describe("getInflatedDataSourceUrl", () => {
  beforeEach(() => {
    reactHooksLogger.warning.mockClear();

    const {
      appStore,
    } = require("@applicaster/zapp-react-native-redux/AppStore");

    mockStore = {
      getState: jest.fn().mockReturnValue({ pipesEndpoints: {} }),
    };

    appStore.set(mockStore);
  });

  it("returns the url inflated with the right params", () => {
    // setup
    const source = "http://foo.com/show/{{showId}}";

    const contexts = {
      entry: { id: "show-1" },
    };

    const mapping = {
      showId: {
        property: "id",
        source: "entry",
      },
    };

    // run
    const result = getInflatedDataSourceUrl({
      source,
      contexts,
      mapping,
    });

    // verify
    expect(result).toBe("http://foo.com/show/show-1");

    expect(reactHooksLogger.warning).not.toHaveBeenCalled();
  });

  it("returns null if required entry is undefined", () => {
    // setup
    const source = "http://foo.com/show/seriesId={{seriesId}}";

    const contexts = {
      entry: undefined,
    };

    const mapping = {
      seriesId: {
        property: "id",
        source: "entry",
      },
    };

    // run
    const result = getInflatedDataSourceUrl({
      source,
      contexts,
      mapping,
    });

    // verify
    expect(result).toBeNull();
    expect(reactHooksLogger.warning).toHaveBeenCalledTimes(1);

    expect(reactHooksLogger.warning).toHaveBeenCalledWith({
      message:
        "Not enough data to fully inflate url: {{entry.id}} source: http://foo.com/show/seriesId={{seriesId}}",
      data: { source, contexts, mapping },
    });
  });

  it("returns null if dont have enough data", () => {
    // setup
    const source =
      "https://zapp-1689-emmys.web.app/emmys/group-categories/{{groupName}}";

    const contexts = {
      entry: {
        extensions: {},
      },
    };

    const mapping = {
      groupName: {
        property: "extensions.groupName",
        source: "entry",
      },
    };

    // run
    const result = getInflatedDataSourceUrl({
      source,
      contexts,
      mapping,
    });

    // verify
    expect(result).toBeNull();
    expect(reactHooksLogger.warning).toHaveBeenCalledTimes(1);

    expect(reactHooksLogger.warning).toHaveBeenCalledWith({
      message:
        "Not enough data to fully inflate url: {{entry.extensions.groupName}} source: https://zapp-1689-emmys.web.app/emmys/group-categories/{{groupName}}",
      data: { source, contexts, mapping },
    });
  });

  it("returns null if dont have enough data", () => {
    // setup
    const source =
      "https://zapp-1689-emmys.web.app/emmys/group-categories/{{groupName1}}?test={{groupName2}}";

    const contexts = {
      entry: {
        extensions: {
          groupName1: "groupName_1",
        },
      },
    };

    const mapping = {
      groupName1: {
        property: "extensions.groupName1",
        source: "entry",
      },
      groupName2: {
        property: "extensions.groupName2",
        source: "entry",
      },
    };

    // run
    const result = getInflatedDataSourceUrl({
      source,
      contexts,
      mapping,
    });

    // verify
    expect(result).toBeNull();
    expect(reactHooksLogger.warning).toHaveBeenCalledTimes(1);

    expect(reactHooksLogger.warning).toHaveBeenCalledWith({
      message:
        "Not enough data to fully inflate url: {{entry.extensions.groupName2}} source: https://zapp-1689-emmys.web.app/emmys/group-categories/{{groupName1}}?test={{groupName2}}",
      data: { source, contexts, mapping },
    });
  });
});

describe("getSearchContext", () => {
  it("returns an object with the search context and the correct prop name", () => {
    // setup
    const searchContext = "query%20typed%20by%20the%20user";

    const mapping = {
      queryParam: {
        property: "q",
        source: "search",
      },
    };

    // run
    const result = getSearchContext(searchContext, mapping);

    // verify
    expect(result).toHaveProperty(mapping.queryParam.property, searchContext);
  });
});
