UNPKG

@applicaster/quick-brick-core

Version:

Core package for Applicaster's Quick Brick App

330 lines (270 loc) • 9.17 kB
import reducer, { ACTIONS, back, initialState, push, replace, } from "../reducer"; jest.mock("uuid"); const screen: ZappRiver = { id: "B5678", name: "Screen name", type: "general_content", home: false, home_offline: false, supports_offline: false, // @ts-ignore navigations: [{ id: "nav_id" }], hooks: { preload_plugins: [] }, }; const screen2: ZappRiver = { id: "C9090", name: "Screen 2 name", type: "general_content", home: false, home_offline: false, supports_offline: false, // @ts-ignore navigations: [{ id: "nav_id" }], hooks: { preload_plugins: [] }, }; const homeScreen: ZappRiver = { id: "A1234", name: "Home", type: "general_content", home: true, home_offline: true, supports_offline: false, // @ts-ignore navigations: [{ id: "nav_id" }], hooks: { preload_plugins: [] }, }; const entry: ZappEntry = { id: "C0987", title: "Entry", type: { value: "feed" }, }; const entry2: ZappEntry = { id: "D1234", title: "Entry 2", type: { value: "video" }, }; describe("ACTIONS", () => { it("matches snapshot", () => { expect(ACTIONS).toMatchSnapshot(); }); }); describe("actions", () => { describe("push", () => { it("returns a push action", () => { const route = "/river/A1234"; const action = push(route, { screen, entry }); expect(action).toHaveProperty("type", ACTIONS.PUSH); expect(action).toHaveProperty( "payload", expect.objectContaining({ route, screen, entry, }) ); }); }); describe("replace", () => { it("returns a replace action", () => { const route = "/river/A1234"; const action = replace(route, { screen, entry }); expect(action).toHaveProperty("type", ACTIONS.REPLACE); expect(action).toHaveProperty( "payload", expect.objectContaining({ route, screen, entry, }) ); }); }); describe("back", () => { it("returns a back action", () => { const backAction = back(); expect(backAction).toHaveProperty("type", ACTIONS.BACK); expect(backAction).toHaveProperty( "payload", expect.objectContaining({ key: expect.any(String), route: "", }) ); }); }); }); describe("reducer", () => { const route = "/river/A1234"; const route2 = "/river/B7890"; it("has the proper inital state", () => { const state = reducer(); expect(state).toEqual(initialState); }); describe("when a push action is dispatched", () => { const action = replace(route, { screen: homeScreen }); const newState = reducer(initialState, action); const action2 = push(route2, { screen, entry }); const newState2 = reducer(newState, action2); it("adds a navigation entry to the stack", () => { expect(newState).toHaveProperty("stack"); // @ts-ignore expect(newState.stack.mainStack).toBeArrayOfSize(1); expect(newState.stack.mainStack[0]).toHaveProperty( "action", ACTIONS.REPLACE ); expect(newState.stack.mainStack[0]).toHaveProperty("route", route); expect(newState.stack.mainStack[0]).toHaveProperty("state", { screen: homeScreen, entry: undefined, }); expect(newState2).toHaveProperty("stack"); // @ts-ignore expect(newState2.stack.mainStack).toBeArrayOfSize(2); expect(newState2.stack.mainStack[0]).toHaveProperty( "action", ACTIONS.REPLACE ); expect(newState2.stack.mainStack[0]).toHaveProperty("route", route); expect(newState2.stack.mainStack[0]).toHaveProperty("state", { screen: homeScreen, entry: undefined, }); expect(newState2.stack.mainStack[1]).toHaveProperty( "action", ACTIONS.PUSH ); expect(newState2.stack.mainStack[1]).toHaveProperty("route", route2); expect(newState2.stack.mainStack[1]).toHaveProperty("state", { screen, entry, }); }); it("leaves navBar properties in state unchanged", () => { expect(newState.options.navBar).toEqual(initialState.options.navBar); expect(newState2.options.navBar).toEqual(initialState.options.navBar); }); }); describe("when a replace action is dispatched", () => { const action = replace(route, { screen: homeScreen }); const newState = reducer(initialState, action); const action2 = replace(route2, { screen, entry }); const newState2 = reducer(newState, action2); it("resets the stack and adds an entry when replace is called", () => { expect(newState).toHaveProperty("stack"); // @ts-ignore expect(newState.stack.mainStack).toBeArrayOfSize(1); expect(newState.stack.mainStack[0]).toHaveProperty( "action", ACTIONS.REPLACE ); expect(newState.stack.mainStack[0]).toHaveProperty("route", route); expect(newState.stack.mainStack[0]).toHaveProperty("state", { screen: homeScreen, entry: undefined, }); expect(newState2).toHaveProperty("stack"); // @ts-ignore expect(newState2.stack.mainStack).toBeArrayOfSize(1); expect(newState2.stack.mainStack[0]).toHaveProperty( "action", ACTIONS.REPLACE ); expect(newState2.stack.mainStack[0]).toHaveProperty("route", route2); expect(newState2.stack.mainStack[0]).toHaveProperty("state", { screen, entry, }); }); it("leaves navBar properties in state unchanged", () => { expect(newState.options.navBar).toEqual(initialState.options.navBar); expect(newState2.options.navBar).toEqual(initialState.options.navBar); }); }); describe("when a back action is dispatched", () => { describe("when there's more than one entry in the stack", () => { const action = replace(route, { screen: homeScreen }); const newState = reducer(initialState, action); const action2 = push(route2, { screen, entry }); const newState2 = reducer(newState, action2); const backAction = back(); const finalState = reducer(newState2, backAction); it("removes the last item when going back and there's more than 1 entry", () => { expect(finalState).toHaveProperty("stack"); // @ts-ignore expect(finalState.stack.mainStack).toBeArrayOfSize( newState2.stack.mainStack.length - 1 ); expect(finalState.stack.mainStack[0]).toHaveProperty( "action", ACTIONS.BACK ); expect(finalState.stack.mainStack[0]).toHaveProperty("route", route); expect(finalState.stack.mainStack[0]).toHaveProperty( "state", expect.objectContaining({ entry: undefined, screen: homeScreen }) ); }); it("leaves navBar properties in state unchanged", () => { expect(newState.options.navBar).toEqual(initialState.options.navBar); expect(newState2.options.navBar).toEqual(initialState.options.navBar); expect(finalState.options.navBar).toEqual(initialState.options.navBar); }); }); describe("push, back, push, back", () => { const route = "/river/A1234"; const route2 = "/river/A1234/river/B7890"; const route3 = "/river/A1234/river/B7890/river/C0987"; const route4 = "/river/A1234/river/B7890/river/D5678"; const action = replace(route, { screen: homeScreen }); const state1 = reducer(initialState, action); const action2 = push(route2, { screen, entry }); const state2 = reducer(state1, action2); const action3 = push(route3, { screen: screen2, entry: entry2 }); const state3 = reducer(state2, action3); const backAction = back(); const state4 = reducer(state3, backAction); const action4 = push(route4, { screen, entry }); const state5 = reducer(state4, action4); const state6 = reducer(state5, backAction); it("does what it's supposed to do", () => { expect(true).toBe(true); expect({ state1, state2, state3, state4, state5, state6, }).toMatchSnapshot(); }); }); describe("when there's only one entry in the stack", () => { const action = replace(route, { screen: homeScreen }); const newState = reducer(initialState, action); const backAction = back(); const finalState = reducer(newState, backAction); it("returns the same entry when going back and there's one entry", () => { expect(finalState).toHaveProperty("stack"); // @ts-ignore expect(finalState.stack.mainStack).toBeArrayOfSize(1); expect(finalState.stack.mainStack[0]).toHaveProperty( "action", ACTIONS.REPLACE ); expect(finalState.stack.mainStack[0]).toHaveProperty("route", route); expect(finalState.stack.mainStack[0]).toHaveProperty("state", { screen: homeScreen, entry: undefined, }); expect(finalState).toEqual(newState); }); }); }); });