@applicaster/quick-brick-core
Version:
Core package for Applicaster's Quick Brick App
330 lines (270 loc) • 9.17 kB
text/typescript
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);
});
});
});
});