[FIX] web, web_editor, website: fix qunit tests

This commit mocks the website service for all the QUnit tests.
As the website module now defines a patch on the WebClient and NavBar
components, adding the website service, this service needs to be mocked
for all the tests. This is done by patching the QUnit.testStart hook.

Also, after the addition of the new media dialog, this component is
mocked at the field html unit test.

See merge commit for more information.

task-2687506
This commit is contained in:
Younn Olivier
2022-06-24 10:28:07 +02:00
committed by qsm-odoo
parent 63c325b17f
commit 85b1ec969e
8 changed files with 95 additions and 43 deletions
@@ -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() {
+6 -1
View File
@@ -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
*/
+3 -1
View File
@@ -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) {
@@ -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 () {
'<p>t<span class="fa fa-glass"></span>to toto toto</p><p>tata</p>',
"should have the image in the dom");
testUtils.mock.unpatch(MediaDialog);
form.destroy();
});
+3
View File
@@ -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'),
],
@@ -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(),
);
}
@@ -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,
@@ -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'));
},
});