import { user } from "@web/core/user"; import { useBackButton } from "@web_mobile/js/core/hooks"; import { accountMethodsForMobile } from "@web_mobile/js/core/mixins"; import { methods as mobileNativeMethods } from "@web_mobile/js/services/core"; import { Popover } from "@web/core/popover/popover"; import { clickSave, contains, defineModels, fields, models, mountView, mountWithCleanup, patchWithCleanup, } from "@web/../tests/web_test_helpers"; import { animationFrame } from "@odoo/hoot-mock"; import { destroy, getFixture, expect, test } from "@odoo/hoot"; import { Component, useState, xml } from "@odoo/owl"; const MY_IMAGE = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; const BASE64_SVG_IMAGE = "PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNzUnIGhlaWdodD0nMTAwJyBmaWxsPScjMDAwJz48cG9seWdvbiBwb2ludHM9JzAsMCAxMDAsMCA1MCw1MCcvPjwvc3ZnPg=="; const BASE64_PNG_HEADER = "iVBORw0KGg"; class Users extends models.Model { name = fields.Char(); } defineModels([Users]); test("component should receive a backbutton event", async () => { patchWithCleanup(mobileNativeMethods, { overrideBackButton({ enabled }) { expect.step(`overrideBackButton: ${enabled}`); }, }); class DummyComponent extends Component { static template = xml`
`; static props = ["*"]; setup() { useBackButton(this._onBackButton); } _onBackButton(ev) { expect.step(`${ev.type} event`); } } const dummy = await mountWithCleanup(DummyComponent); // simulate 'backbutton' event triggered by the app document.dispatchEvent(new Event("backbutton")); expect.verifySteps(["overrideBackButton: true", "backbutton event"]); destroy(dummy); expect.verifySteps(["overrideBackButton: false"]); }); test("multiple components should receive backbutton events in the right order", async () => { patchWithCleanup(mobileNativeMethods, { overrideBackButton({ enabled }) { expect.step(`overrideBackButton: ${enabled}`); }, }); class DummyComponent extends Component { static template = xml`
`; static props = ["*"]; setup() { useBackButton(this._onBackButton); } _onBackButton(ev) { expect.step(`${this.props.name}: ${ev.type} event`); // unmounting is not supported anymore // A real business case equivalent to this is to have a Parent component // doing a foreach on some reactive object which contains the list of dummy components // and calling a callback props.onBackButton right here that removes the element from the list destroy(this); } } await mountWithCleanup(DummyComponent, { props: { name: "dummy1" } }); await mountWithCleanup(DummyComponent, { props: { name: "dummy2" } }); await mountWithCleanup(DummyComponent, { props: { name: "dummy3" } }); // simulate 'backbutton' events triggered by the app document.dispatchEvent(new Event("backbutton")); document.dispatchEvent(new Event("backbutton")); document.dispatchEvent(new Event("backbutton")); expect.verifySteps([ "overrideBackButton: true", "dummy3: backbutton event", "dummy2: backbutton event", "dummy1: backbutton event", "overrideBackButton: false", ]); }); test("component should receive a backbutton event: custom activation", async () => { patchWithCleanup(mobileNativeMethods, { overrideBackButton({ enabled }) { expect.step(`overrideBackButton: ${enabled}`); }, }); class DummyComponent extends Component { static template = xml`