import React from "react"; import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils"; import { getInflatedDataSourceUrl, getSearchContext, useGetUrlInflater, } from "../useInflatedUrl"; import { reactHooksLogger } from "../../logger"; jest.mock("../../navigation", () => ({ useRoute: () => ({ pathname: "/mock/path" }), })); // mock contexts hooks jest.mock("@applicaster/zapp-react-native-ui-components/Contexts", () => ({ ZappPipesEntryContext: { useZappPipesContext: () => [ { id: "entry-1", extensions: { showId: "A123" } }, ], }, ZappPipesSearchContext: { useZappPipesContext: () => ["user%20query"], }, ZappPipesScreenContext: { useZappPipesContext: () => [{ id: "screen-1" }], }, })); jest.mock("../../logger", () => ({ reactHooksLogger: { warning: jest.fn(), addSubsystem: jest.fn(), }, })); 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); }); }); describe("useGetUrlInflater", () => { const { renderHook } = require("@testing-library/react-hooks"); it("returns original url when mapping is not provided", () => { const { result } = renderHook(() => useGetUrlInflater(), { wrapper: WrappedWithProviders, }); const src = "https://foo.com/feed"; expect(result.current(src)).toBe(src); }); it("inflates url using entry/search/screen contexts when mapping provided", () => { const { result } = renderHook(() => useGetUrlInflater(), { wrapper: ({ children }) => ( {children} ), }); const source = "https://foo.com/shows/{{showId}}?q={{q}}"; const mapping = { showId: { source: "entry", property: "extensions.showId" }, q: { source: "search", property: "q" }, }; const url = result.current(source, mapping); expect(url).toBe("https://foo.com/shows/A123?q=user%20query"); }); });