import { load, makePage, makeScreen, walkComponentTree } from "./testAppDef" import { isScreenSlot } from "../src/render/builtinComponents" jest.mock("../src/render/getAppId", () => ({ getAppId: () => "TEST_APP_ID" })) describe("screenRouting", () => { it("should load correct screen, for initial URL", async () => { const { page, screens } = pageWith3Screens() const { dom } = await load(page, screens, "/screen2") const rootDiv = dom.window.document.body.children[0] expect(rootDiv.children.length).toBe(1) const screenRoot = rootDiv.children[0] expect(screenRoot.children.length).toBe(1) expect(screenRoot.children[0].children.length).toBe(1) expect(screenRoot.children[0].children[0].innerText).toBe("screen 2") }) it("should load correct screen, for initial URL, when appRootPath is something", async () => { const { page, screens } = pageWith3Screens() const { dom } = await load(page, screens, "/TEST_APP_ID/screen2", "127.0.0.1") const rootDiv = dom.window.document.body.children[0] expect(rootDiv.children.length).toBe(1) const screenRoot = rootDiv.children[0] expect(screenRoot.children.length).toBe(1) expect(screenRoot.children[0].children.length).toBe(1) expect(screenRoot.children[0].children[0].innerText).toBe("screen 2") }) it("should be able to route to the correct screen", async () => { const { page, screens } = pageWith3Screens() const { dom, app } = await load(page, screens, "/screen2") app.routeTo()("/screen3") const rootDiv = dom.window.document.body.children[0] expect(rootDiv.children.length).toBe(1) const screenRoot = rootDiv.children[0] expect(screenRoot.children.length).toBe(1) expect(screenRoot.children[0].children.length).toBe(1) expect(screenRoot.children[0].children[0].innerText).toBe("screen 3") }) it("should be able to route to the correct screen, when appRootPath is something", async () => { const { page, screens } = pageWith3Screens() const { dom, app } = await load( page, screens, "/TEST_APP_ID/screen2", "127.0.0.1" ) app.routeTo()("/screen3") const rootDiv = dom.window.document.body.children[0] expect(rootDiv.children.length).toBe(1) const screenRoot = rootDiv.children[0] expect(screenRoot.children.length).toBe(1) expect(screenRoot.children[0].children.length).toBe(1) expect(screenRoot.children[0].children[0].innerText).toBe("screen 3") }) it("should destroy and unsubscribe all components on a screen whe screen is changed", async () => { const { page, screens } = pageWith3Screens() const { app } = await load(page, screens, "/screen2") const nodes = createTrackerNodes(app) app.routeTo()("/screen3") expect(nodes.length > 0).toBe(true) expect( nodes.some(n => n.isDestroyed === false && isUnderScreenSlot(n.node)) ).toBe(false) expect( nodes.some(n => n.isUnsubscribed === false && isUnderScreenSlot(n.node)) ).toBe(false) }) it("should not destroy and unsubscribe page and screenslot components when screen is changed", async () => { const { page, screens } = pageWith3Screens() const { app } = await load(page, screens, "/screen2") const nodes = createTrackerNodes(app) app.routeTo()("/screen3") expect(nodes.length > 0).toBe(true) expect( nodes.some(n => n.isDestroyed === true && !isUnderScreenSlot(n.node)) ).toBe(false) }) }) const createTrackerNodes = app => { const nodes = [] walkComponentTree(app.rootNode(), n => { if (!n.component) return const tracker = { node: n, isDestroyed: false, isUnsubscribed: false } const _destroy = n.component.$destroy n.component.$destroy = () => { _destroy() tracker.isDestroyed = true } const _unsubscribe = n.unsubscribe if (!_unsubscribe) { tracker.isUnsubscribed = undefined } else { n.unsubscribe = () => { _unsubscribe() tracker.isUnsubscribed = true } } nodes.push(tracker) }) return nodes } const isUnderScreenSlot = node => node.parentNode && (isScreenSlot(node.parentNode.props._component) || isUnderScreenSlot(node.parentNode)) const pageWith3Screens = () => ({ page: makePage({ _component: "testlib/div", _children: [ { _component: "##builtin/screenslot", text: "header one", }, ], }), screens: [ makeScreen("/", { _component: "testlib/div", className: "screen-class", _children: [ { _component: "testlib/h1", text: "screen 1", }, ], }), makeScreen("/screen2", { _component: "testlib/div", className: "screen-class", _children: [ { _component: "testlib/h1", text: "screen 2", }, ], }), makeScreen("/screen3", { _component: "testlib/div", className: "screen-class", _children: [ { _component: "testlib/h1", text: "screen 3", }, ], }), ], })