UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

387 lines (316 loc) • 11.3 kB
import * as R from "ramda"; import * as navigationUtils from ".."; import { river, riverPlugin, riverFeed, article, menuItem, content, riverPluginPlayable, } from "./fixtures"; import { SCREEN_TYPES } from "../itemTypes"; describe("getNavigationType", () => { const { getNavigationType } = navigationUtils; const navigations = [ { category: "nav_bar", navigation_type: "navigation_bar", }, { category: "menu", navigation_type: "side_menu", }, ]; it("returns the type of navigation for a category", () => { expect(getNavigationType("menu", navigations)).toBe("side_menu"); }); it("returns null if the category can't be found", () => { expect(getNavigationType("some_nav", navigations)).toBeUndefined(); }); }); describe("resolveNavigationPlugin", () => { const { resolveNavigationPlugin } = navigationUtils; const defaultNav = { module: jest.fn(), name: "default nav", identifier: "default_nav", type: "menu", default: true, }; const otherDefaultPlugin = { module: jest.fn(), name: "some default plugin", identifier: "Default_Plugin", type: "player", default: true, }; const optionalNav = { module: jest.fn(), name: "Optional nav", identifier: "optional_nav", type: "menu", }; const plugins = [defaultNav, otherDefaultPlugin, optionalNav]; const category = "menu"; it("returns null if navigation type cannot be found", () => { const navigations = []; expect(resolveNavigationPlugin({ category, navigations, plugins })).toBe( null ); }); it("returns the plugin matching the navigation type if it exists", () => { const navigations = [ { category: "menu", navigation_type: "optional_nav", }, ]; expect(resolveNavigationPlugin({ category, navigations, plugins })).toEqual( optionalNav ); }); it("returns the default plugin otherwise", () => { const navigations = [ { category: "menu", navigation_type: "unknown_nav", }, ]; expect(resolveNavigationPlugin({ category, navigations, plugins })).toEqual( defaultNav ); }); it("returns the default plugin if there's no other", () => { const navigations = [ { category: "menu", navigation_type: "any_plugin", }, ]; expect( resolveNavigationPlugin({ category, navigations, plugins: [defaultNav] }) ).toEqual(defaultNav); }); }); describe("getNavigationProps", () => { const { getNavigationProps } = navigationUtils; const baseScreen = { id: "A1234", name: "base screen", home: false, }; const category = "menu"; it("returns null if the screen has no navigation props", () => { const navigations = []; const navigator = { activeRiver: R.merge(baseScreen, { navigations }), }; expect(getNavigationProps({ navigator, category })).toBe(null); }); it("returns the props otherwise", () => { const navigations = [ { category: "menu", styles: { style: "foo" }, assets: { appLogo: "appLogo.png" }, nav_items: [{ type: "label" }], rules: {}, }, ]; const navigator = { screenTitle: "base screen", activeRiver: R.merge(baseScreen, { navigations }), }; expect( getNavigationProps({ navigator, title: "testTitle", category }) ).toMatchSnapshot(); }); }); describe("getPathAttributes", () => { const getLocation = (pathname) => ({ pathname }); const { getPathAttributes } = navigationUtils; it("returns an empty array if path is empty", () => { const location = getLocation(""); expect(getPathAttributes(location)).toEqual([]); }); it("returns an empty array if path is /", () => { const location = getLocation("/"); expect(getPathAttributes(location)).toEqual([]); }); it("forms the path attributes", () => { const location = getLocation("/river/A1234/someScreen/B456"); expect(getPathAttributes(location)).toEqual([ { screenType: "river", screenId: "A1234" }, { screenType: "someScreen", screenId: "B456" }, ]); }); }); describe("getItemType", () => { const { getItemType } = navigationUtils; describe("layouts v1", () => { it("returns the type of an item", () => { expect(getItemType(river, "v1")).toBe("river"); expect(getItemType(riverFeed, "v1")).toBe("river"); expect(getItemType(menuItem, "v1")).toBe("menu_item"); expect(getItemType(article, "v1")).toBe("article"); expect(getItemType(content, "v1")).toBe("content_screen"); }); }); describe("layouts v2", () => { it("returns the type of an item", () => { expect(getItemType(river, "v2")).toBe("river"); expect(getItemType(riverFeed, "v2")).toBe("river"); expect(getItemType(menuItem, "v2")).toBe("river"); expect(getItemType(article, "v2")).toBe("river"); expect(getItemType(content, "v2")).toBe("river"); }); }); }); describe("getItemTargetId", () => { const { getItemTargetId } = navigationUtils; it("returns the target id of an item", () => { expect(getItemTargetId(river, "river")).toBe(river.id); expect(getItemTargetId(riverFeed, "river")).toBe(riverFeed.riverId); expect(getItemTargetId(menuItem, "menu_item")).toBe(menuItem.data.target); expect(getItemTargetId(article, "article")).toBe(article.id); expect(getItemTargetId(content, "content_screen")).toBe(content.id); }); }); describe("getTargetRoute", () => { const { getItemType, getItemTargetId, getTargetRoute } = navigationUtils; describe("layout v1", () => { const layoutVersion = "v1"; it("returns the target route for a given item", () => { const pathname = "/foo"; const riverType = getItemType(river, layoutVersion); const riverId = getItemTargetId(river, riverType); expect(getTargetRoute(river, pathname, { layoutVersion })).toBe( `${pathname}/${riverType}/${riverId}` ); }); it("returns the target route for an item that is not a menu item", () => { const pathname = "/foo"; const articleType = getItemType(article, layoutVersion); const articleId = getItemTargetId(article, articleType); expect(getTargetRoute(article, pathname, { layoutVersion })).toBe( `${pathname}/${articleType}/${articleId}` ); }); it("returns a valid path when initial pathname is /", () => { const targetRoute = getTargetRoute(river, "/", { layoutVersion }); expect(targetRoute).toEqual(`/river/${river.id}`); expect(targetRoute).not.toInclude("//"); }); }); describe("layout v2", () => { const layoutVersion = "v2"; it("returns the target route for a given item", () => { const pathname = "/foo"; const riverType = getItemType(river, layoutVersion); const riverId = getItemTargetId(river, riverType); expect(getTargetRoute(river, pathname, { layoutVersion })).toBe( `${pathname}/${riverType}/${riverId}` ); }); it("returns the target route for an item that is not a menu item", () => { const pathname = "/foo"; const articleType = getItemType(article, layoutVersion); const articleId = getItemTargetId(article, articleType); expect(getTargetRoute(article, pathname, { layoutVersion })).toBe( `${pathname}/${articleType}/${articleId}` ); }); it("returns a valid path when initial pathname is /", () => { const targetRoute = getTargetRoute(river, "/", { layoutVersion }); expect(targetRoute).toEqual(`/river/${river.id}`); expect(targetRoute).not.toInclude("//"); }); }); }); describe("getRiverFromRoute", () => { const { getRiverFromRoute } = navigationUtils; const rivers = { [river.id]: river, [riverFeed.id]: riverFeed, [riverPlugin.id]: riverPlugin, [riverPluginPlayable.id]: riverPluginPlayable, }; it("returns null if the route is not valid", () => { const route = "foo-bar"; expect(getRiverFromRoute({ route, rivers })).toBe(null); }); it("returns the screen type & screen id if it cannot find a river", () => { const route = "/article/A123"; expect(getRiverFromRoute({ route: route, rivers })).toEqual({ screenType: "article", screenId: "A123", }); }); it("returns the plugin screen if the river points to a plugin screen ", () => { const route = `/river/${river.id}/${riverPlugin.type}/SOME_ID`; expect(getRiverFromRoute({ route, rivers })).toEqual(riverPlugin); }); it("returns the plugin screen if the river points to a player screen ", () => { const route = `/river/${river.id}/${SCREEN_TYPES.PLAYABLE}/SOME_ID`; expect(getRiverFromRoute({ route, rivers })).toEqual(riverPluginPlayable); }); it("returns the river if the route path is a a river path", () => { const route = `/river/${river.id}`; expect(getRiverFromRoute({ route, rivers })).toEqual(river); }); }); describe("isPreviousRouteHook", () => { const { isPreviousRouteHook } = navigationUtils; const history = { entries: [], }; it("returns false if it's a root route", () => { history.entries.push({ pathname: "/river/root" }); const currentResult = isPreviousRouteHook(history.entries); expect(currentResult).toBe(false); }); it("returns false if previous root is not a hook", () => { history.entries.push({ pathname: "/almostHooks/secondLevel" }); const currentResult = isPreviousRouteHook(history.entries); expect(currentResult).toBe(false); }); it("returns true if previous root is a hook", () => { history.entries.push({ pathname: "/hooks/ThirdLevel" }); history.entries.push({ pathname: "/almostHooks/forthLevel" }); const currentResult = isPreviousRouteHook(history.entries); expect(currentResult).toBe(true); }); }); describe("getPreviousHooksCount", () => { const { getPreviousHooksCount } = navigationUtils; const history = { entries: [], }; it("returns 0 if it's a root route", () => { history.entries.push({ pathname: "/river/root" }); const currentResult = getPreviousHooksCount(history); expect(currentResult).toBe(0); }); it("returns 0 if previous root is not a hook", () => { history.entries.push({ pathname: "/almostHooks/secondLevel" }); const currentResult = getPreviousHooksCount(history); expect(currentResult).toBe(0); }); it("returns 1 if previous root is a hook", () => { history.entries = []; history.entries.push({ pathname: "/hooks/ThirdLevel" }); history.entries.push({ pathname: "/almostHooks/forthLevel" }); const currentResult = getPreviousHooksCount(history); expect(currentResult).toBe(1); }); it("returns 2 if 2 previous routes are a hooks", () => { history.entries = []; history.entries.push({ pathname: "/almostHooks/forthLevel" }); history.entries.push({ pathname: "/hooks/myHook" }); history.entries.push({ pathname: "/hooks/myHook" }); history.entries.push({ pathname: "/almostHooks/forthLevel" }); const currentResult = getPreviousHooksCount(history); expect(currentResult).toBe(2); }); });