/*eslint max-nested-callbacks: ["error", 10]*/ import { ASRouterNewTabHook } from "lib/ASRouterNewTabHook.sys.mjs"; describe("ASRouterNewTabHook", () => { let sandbox = null; let initParams = null; beforeEach(() => { sandbox = sinon.createSandbox(); initParams = { router: { init: sandbox.stub().callsFake(() => { // Fake the initialization initParams.router.initialized = true; }), uninit: sandbox.stub(), }, messageHandler: { handleCFRAction: {}, handleTelemetry: {}, }, createStorage: () => Promise.resolve({}), }; }); afterEach(() => { sandbox.restore(); }); describe("ASRouterNewTabHook", () => { describe("getInstance", () => { it("awaits createInstance and router init before returning instance", async () => { const getInstanceCall = sandbox.spy(); const waitForInstance = ASRouterNewTabHook.getInstance().then(getInstanceCall); await ASRouterNewTabHook.createInstance(initParams); await waitForInstance; assert.callOrder(initParams.router.init, getInstanceCall); }); }); describe("createInstance", () => { it("calls router init", async () => { await ASRouterNewTabHook.createInstance(initParams); assert.calledOnce(initParams.router.init); }); it("only calls router init once", async () => { initParams.router.init.callsFake(() => { initParams.router.initialized = true; }); await ASRouterNewTabHook.createInstance(initParams); await ASRouterNewTabHook.createInstance(initParams); assert.calledOnce(initParams.router.init); }); }); describe("destroy", () => { it("disconnects new tab, uninits ASRouter, and destroys instance", async () => { await ASRouterNewTabHook.createInstance(initParams); const instance = await ASRouterNewTabHook.getInstance(); const destroy = instance.destroy.bind(instance); sandbox.stub(instance, "destroy").callsFake(destroy); ASRouterNewTabHook.destroy(); assert.calledOnce(initParams.router.uninit); assert.calledOnce(instance.destroy); assert.isNotNull(instance); assert.isNull(instance._newTabMessageHandler); }); }); describe("instance", () => { let routerParams = null; let messageHandler = null; let instance = null; beforeEach(async () => { messageHandler = { clearChildMessages: sandbox.stub().resolves(), clearChildProviders: sandbox.stub().resolves(), updateAdminState: sandbox.stub().resolves(), }; initParams.router.init.callsFake(params => { routerParams = params; }); await ASRouterNewTabHook.createInstance(initParams); instance = await ASRouterNewTabHook.getInstance(); }); describe("connect", () => { it("before connection messageHandler methods are not called", async () => { routerParams.clearChildMessages([1]); routerParams.clearChildProviders(["snippets"]); routerParams.updateAdminState({ messages: {} }); assert.notCalled(messageHandler.clearChildMessages); assert.notCalled(messageHandler.clearChildProviders); assert.notCalled(messageHandler.updateAdminState); }); it("after connect updateAdminState and clearChildMessages calls are forwarded to handler", async () => { instance.connect(messageHandler); routerParams.clearChildMessages([1]); routerParams.clearChildProviders(["snippets"]); routerParams.updateAdminState({ messages: {} }); assert.called(messageHandler.clearChildMessages); assert.called(messageHandler.clearChildProviders); assert.called(messageHandler.updateAdminState); }); it("calls from before connection are dropped", async () => { routerParams.clearChildMessages([1]); routerParams.clearChildProviders(["snippets"]); routerParams.updateAdminState({ messages: {} }); instance.connect(messageHandler); routerParams.clearChildMessages([1]); routerParams.clearChildProviders(["snippets"]); routerParams.updateAdminState({ messages: {} }); assert.calledOnce(messageHandler.clearChildMessages); assert.calledOnce(messageHandler.clearChildProviders); assert.calledOnce(messageHandler.updateAdminState); }); }); describe("disconnect", () => { it("calls after disconnect are dropped", async () => { instance.connect(messageHandler); instance.disconnect(); routerParams.clearChildMessages([1]); routerParams.clearChildProviders(["snippets"]); routerParams.updateAdminState({ messages: {} }); assert.notCalled(messageHandler.clearChildMessages); assert.notCalled(messageHandler.clearChildProviders); assert.notCalled(messageHandler.updateAdminState); }); it("only calls from when there is a connection are forwarded", async () => { routerParams.clearChildMessages([1]); routerParams.clearChildProviders(["foo"]); routerParams.updateAdminState({ messages: {} }); instance.connect(messageHandler); routerParams.clearChildMessages([200]); routerParams.clearChildProviders(["bar"]); routerParams.updateAdminState({ messages: { data: "accept", }, }); instance.disconnect(); routerParams.clearChildMessages([1]); routerParams.clearChildProviders(["foo"]); routerParams.updateAdminState({ messages: {} }); assert.calledOnce(messageHandler.clearChildMessages); assert.calledOnce(messageHandler.clearChildProviders); assert.calledOnce(messageHandler.updateAdminState); assert.calledWith(messageHandler.clearChildMessages, [200]); assert.calledWith(messageHandler.clearChildProviders, ["bar"]); assert.calledWith(messageHandler.updateAdminState, { messages: { data: "accept", }, }); }); }); }); }); });