diff --git a/addons/web/static/tests/core/debug/debug_manager_tests.js b/addons/web/static/tests/core/debug/debug_manager_tests.js index da9b649d94e..313bacf90ed 100644 --- a/addons/web/static/tests/core/debug/debug_manager_tests.js +++ b/addons/web/static/tests/core/debug/debug_manager_tests.js @@ -10,7 +10,7 @@ import { uiService } from "@web/core/ui/ui_service"; import { useSetupView } from "@web/views/helpers/view_hook"; import { ActionDialog } from "@web/webclient/actions/action_dialog"; import { hotkeyService } from "@web/core/hotkeys/hotkey_service"; -import { makeTestEnv, prepareRegistriesWithCleanup } from "../../helpers/mock_env"; +import { makeTestEnv, utils } from "../../helpers/mock_env"; import { fakeCommandService, makeFakeDialogService, @@ -31,6 +31,7 @@ import { editSearchView, editView } from "@web/views/debug_items"; import { setDefaults } from "@web/legacy/debug_manager"; const { Component, xml } = owl; +const { prepareRegistriesWithCleanup } = utils; export class DebugMenuParent extends Component { setup() { diff --git a/addons/web/static/tests/helpers/mock_env.js b/addons/web/static/tests/helpers/mock_env.js index 4233d1f4f39..47204fb7249 100644 --- a/addons/web/static/tests/helpers/mock_env.js +++ b/addons/web/static/tests/helpers/mock_env.js @@ -44,7 +44,7 @@ export function clearServicesMetadataWithCleanup() { registerCleanup(() => patch(SERVICES_METADATA, servicesMetadata)); } -export function prepareRegistriesWithCleanup() { +function prepareRegistriesWithCleanup() { // Clone registries cloneRegistryWithCleanup(registry.category("actions")); cloneRegistryWithCleanup(registry.category("views")); @@ -72,6 +72,11 @@ export function prepareRegistriesWithCleanup() { // better design for the way we clear these registries... } +// This is exported in a utils object to allow for patching +export const utils = { + prepareRegistriesWithCleanup, +}; + /** * @typedef {import("@web/env").OdooEnv} OdooEnv */ diff --git a/addons/web/static/tests/setup.js b/addons/web/static/tests/setup.js index a85f5168aee..5f5d584a0b2 100644 --- a/addons/web/static/tests/setup.js +++ b/addons/web/static/tests/setup.js @@ -6,7 +6,7 @@ import { browser, makeRAMLocalStorage } from "@web/core/browser/browser"; import { patchTimeZone, patchWithCleanup } from "@web/../tests/helpers/utils"; import { legacyProm } from "web.test_legacy"; import { registerCleanup } from "./helpers/cleanup"; -import { prepareRegistriesWithCleanup } from "./helpers/mock_env"; +import { utils } from "./helpers/mock_env"; import { session as sessionInfo } from "@web/session"; import { prepareLegacyRegistriesWithCleanup } from "./helpers/legacy_env_utils"; import { config as transitionConfig } from "@web/core/transition"; @@ -17,6 +17,8 @@ import { patch } from "@web/core/utils/patch"; import { processTemplates } from "@web/core/assets"; const { App, whenReady, loadFile } = owl; +const { prepareRegistriesWithCleanup } = utils; + patch(App.prototype, "TestOwlApp", { destroy() { if (!this.destroyed) { diff --git a/addons/web_editor/static/tests/field_html_tests.js b/addons/web_editor/static/tests/field_html_tests.js index 19c62309a46..1049adf6866 100644 --- a/addons/web_editor/static/tests/field_html_tests.js +++ b/addons/web_editor/static/tests/field_html_tests.js @@ -8,11 +8,13 @@ var testUtils = require('web.test_utils'); var weTestUtils = require('web_editor.test_utils'); var core = require('web.core'); var Wysiwyg = require('web_editor.wysiwyg'); -var MediaDialog = require('wysiwyg.widgets.MediaDialog'); +const { MediaDialogWrapper } = require('@web_editor/components/media_dialog/media_dialog'); var LinkDialog = require('wysiwyg.widgets.LinkDialog'); const { legacyExtraNextTick, patchWithCleanup } = require("@web/../tests/helpers/utils"); +const { useEffect } = owl; + var _t = core._t; let _formResolveTestPromise; @@ -347,34 +349,36 @@ QUnit.module('web_editor', {}, function () { await testUtils.form.clickEdit(form); var $field = form.$('.oe_form_field[name="body"]'); - // the dialog load some xml assets - var defMediaDialog = testUtils.makeTestPromise(); - testUtils.mock.patch(MediaDialog, { - init: function () { - this._super.apply(this, arguments); - this.opened(defMediaDialog.resolve.bind(defMediaDialog)); - } - }); - var pText = $field.find('.note-editable p').first().contents()[0]; Wysiwyg.setRange(pText, 1, pText, 2); await new Promise((resolve) => setTimeout(resolve)); const wysiwyg = $field.find('.note-editable').data('wysiwyg'); + + // Mock the MediaDialogWrapper + const defMediaDialog = testUtils.makeTestPromise(); + patchWithCleanup(MediaDialogWrapper.prototype, { + setup() { + useEffect(() => { + this.save(); + }, () => []); + }, + save() { + const imageEl = document.createElement('img'); + imageEl.src = '/web/image/123/transparent.png'; + this.props.save(imageEl); + defMediaDialog.resolve(); + }, + }); + wysiwyg.openMediaDialog(); - - // load static xml file (dialog, media dialog, unsplash image widget) await defMediaDialog; - await testUtils.dom.click($('.modal #editor-media-image .o_existing_attachment_cell:first').removeClass('d-none')); - var $editable = form.$('.oe_form_field[name="body"] .note-editable'); assert.ok($editable.find('img')[0].dataset.src.includes('/web/image/123/transparent.png'), "should have the image in the dom"); - testUtils.mock.unpatch(MediaDialog); - form.destroy(); }); @@ -402,26 +406,30 @@ QUnit.module('web_editor', {}, function () { await testUtils.form.clickEdit(form); var $field = form.$('.oe_form_field[name="body"]'); - // the dialog load some xml assets - var defMediaDialog = testUtils.makeTestPromise(); - testUtils.mock.patch(MediaDialog, { - init: function () { - this._super.apply(this, arguments); - this.opened(defMediaDialog.resolve.bind(defMediaDialog)); - } - }); var pText = $field.find('.note-editable p').first().contents()[0]; Wysiwyg.setRange(pText, 1, pText, 2); const wysiwyg = $field.find('.note-editable').data('wysiwyg'); - wysiwyg.openMediaDialog(); - // load static xml file (dialog, media dialog, unsplash image widget) + // Mock the MediaDialogWrapper + const defMediaDialog = testUtils.makeTestPromise(); + patchWithCleanup(MediaDialogWrapper.prototype, { + setup() { + useEffect(() => { + this.save(); + }, () => []); + }, + save() { + const iconEl = document.createElement('span'); + iconEl.classList.add('fa', 'fa-glass'); + this.props.save(iconEl); + defMediaDialog.resolve(); + }, + }); + + wysiwyg.openMediaDialog(); await defMediaDialog; - $('.modal .tab-content .tab-pane').removeClass('fade'); // to be sync in test - await testUtils.dom.click($('.modal a[aria-controls="editor-media-icon"]')); - await testUtils.dom.click($('.modal #editor-media-icon .font-icons-icon.fa-glass')); var $editable = form.$('.oe_form_field[name="body"] .note-editable'); @@ -429,8 +437,6 @@ QUnit.module('web_editor', {}, function () { '

tto toto toto

tata

', "should have the image in the dom"); - testUtils.mock.unpatch(MediaDialog); - form.destroy(); }); diff --git a/addons/website/__manifest__.py b/addons/website/__manifest__.py index b6a0cb53598..4e3a07ab426 100644 --- a/addons/website/__manifest__.py +++ b/addons/website/__manifest__.py @@ -183,6 +183,9 @@ 'website/static/tests/dashboard_tests.js', 'website/static/tests/website_tests.js', ], + 'web.tests_assets': [ + 'website/static/tests/website_service_mock.js', + ], 'web._assets_frontend_helpers': [ ('prepend', 'website/static/src/scss/bootstrap_overridden.scss'), ], diff --git a/addons/website/static/src/components/navbar/navbar.js b/addons/website/static/src/components/navbar/navbar.js index d89fe6516f4..3dbb292448a 100644 --- a/addons/website/static/src/components/navbar/navbar.js +++ b/addons/website/static/src/components/navbar/navbar.js @@ -16,8 +16,6 @@ patch(NavBar.prototype, 'website_navbar', { setup() { this._super(); this.websiteService = useService('website'); - this.dialogService = useService('dialog'); - this.user = useService('user'); this.websiteContext = useState(this.websiteService.context); this.aceEditor = WebsiteAceEditor; @@ -41,11 +39,11 @@ patch(NavBar.prototype, 'website_navbar', { this.websiteEditingMenus = { 'website.menu_edit_menu': { - component: EditMenuDialog, + Component: EditMenuDialog, isDisplayed: () => !!this.websiteService.currentWebsite, }, 'website.menu_optimize_seo': { - component: OptimizeSEODialog, + Component: OptimizeSEODialog, isDisplayed: () => this.websiteService.currentWebsite && !!this.websiteService.currentWebsite.metadata.mainObject, }, 'website.menu_ace_editor': { @@ -59,7 +57,7 @@ patch(NavBar.prototype, 'website_navbar', { }; onWillStart(async () => { - this.isWebsitePublisher = await this.user.hasGroup('website.group_website_publisher'); + this.isWebsitePublisher = await this.websiteService.isPublisher(); }); }, @@ -112,8 +110,8 @@ patch(NavBar.prototype, 'website_navbar', { if (websiteMenu) { return websiteMenu.openWidget ? websiteMenu.openWidget() : - this.dialogService.add( - websiteMenu.component, + this.websiteService.openMenuDialog( + websiteMenu.Component, websiteMenu.getProps && websiteMenu.getProps(), ); } diff --git a/addons/website/static/src/services/website_service.js b/addons/website/static/src/services/website_service.js index abad2e76e34..50cadc48a58 100644 --- a/addons/website/static/src/services/website_service.js +++ b/addons/website/static/src/services/website_service.js @@ -23,8 +23,8 @@ export const unslugHtmlDataObject = (repr) => { }; export const websiteService = { - dependencies: ['orm', 'action', 'hotkey'], - async start(env, { orm, action, hotkey }) { + dependencies: ['orm', 'action', 'user', 'dialog', 'hotkey'], + async start(env, { orm, action, user, dialog, hotkey }) { let websites = []; let currentWebsiteId; let currentMetadata = {}; @@ -120,6 +120,12 @@ export const websiteService = { get editedObjectPath() { return editedObjectPath; }, + isPublisher() { + return user.hasGroup('website.group_website_publisher'); + }, + openMenuDialog(Component, props) { + return dialog.add(Component, props); + }, goToWebsite({ websiteId, path, edition, translation } = {}) { action.doAction('website.website_preview', { clearBreadcrumbs: true, diff --git a/addons/website/static/tests/website_service_mock.js b/addons/website/static/tests/website_service_mock.js new file mode 100644 index 00000000000..c89e167f041 --- /dev/null +++ b/addons/website/static/tests/website_service_mock.js @@ -0,0 +1,31 @@ +/** @odoo-module */ + +import { patch } from '@web/core/utils/patch'; +import { registry } from '@web/core/registry'; +import { utils, clearRegistryWithCleanup } from '@web/../tests/helpers/mock_env'; + +const { prepareRegistriesWithCleanup } = utils; + +function makeFakeWebsiteService() { + return { + start() { + return { + get context() { + return {}; + }, + isPublisher() { + return true; + }, + }; + } + }; +} + +const serviceRegistry = registry.category('services'); +patch(utils, 'website_test_registries', { + prepareRegistriesWithCleanup() { + prepareRegistriesWithCleanup(...arguments); + serviceRegistry.add('website', makeFakeWebsiteService()); + clearRegistryWithCleanup(registry.category('website_systray')); + }, +});