[MOV] test_website, web_editor: move test to right module

Some web_editor test was in "test_website" when it could
have simply been in web_editor.

It is moved there and modified to reuse existing imports and pass standard
web linting rules.

task-3741858

closes odoo/odoo#155704

Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
Renaud Thiry
2024-03-29 09:12:17 +00:00
parent 5c7e377f77
commit 8d99f2f415
6 changed files with 208 additions and 174 deletions
-3
View File
@@ -43,9 +43,6 @@ models which only purpose is to run tests.""",
'web.assets_tests': [
'test_website/static/tests/tours/*',
],
'web.qunit_suite_tests': [
'test_website/static/tests/*.js',
],
},
'license': 'LGPL-3',
}
@@ -1,168 +0,0 @@
/** @odoo-module **/
import { FileSelectorControlPanel } from '@web_editor/components/media_dialog/file_selector';
import { getFixture, patchWithCleanup } from "@web/../tests/helpers/utils";
import { HtmlField } from '@web_editor/js/backend/html_field';
import {registry} from '@web/core/registry';
import testUtils from '@web/../tests/legacy/helpers/test_utils';
import { uploadService } from '@web_editor/components/upload_progress_toast/upload_service';
import { unsplashService } from '@web_unsplash/services/unsplash_service';
import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
import { click } from "@web/../tests/utils";
import weTestUtils from '@web_editor/../tests/test_utils';
import {Wysiwyg} from '@web_editor/js/wysiwyg/wysiwyg';
import { useEffect } from "@odoo/owl";
QUnit.module('field html file upload', {
beforeEach: function () {
this.data = weTestUtils.wysiwygData({
'mail.compose.message': {
fields: {
display_name: {
string: "Displayed name",
type: "char"
},
body: {
string: "Message Body inline (to send)",
type: "html"
},
attachment_ids: {
string: "Attachments",
type: "many2many",
relation: "ir.attachment",
}
},
records: [{
id: 1,
display_name: "Some Composer",
body: "Hello",
attachment_ids: [],
}],
},
});
},
}, function () {
QUnit.test('media dialog: upload', async function (assert) {
assert.expect(8);
const onAttachmentChangeTriggered = testUtils.makeTestPromise();
patchWithCleanup(HtmlField.prototype, {
_onAttachmentChange(event) {
super._onAttachmentChange(event);
onAttachmentChangeTriggered.resolve(true);
}
});
const defFileSelector = testUtils.makeTestPromise();
const onChangeTriggered = testUtils.makeTestPromise();
const webSaveTriggered = testUtils.makeTestPromise();
patchWithCleanup(FileSelectorControlPanel.prototype, {
setup() {
super.setup();
useEffect(() => {
defFileSelector.resolve(true);
}, () => []);
},
async onChangeFileInput() {
super.onChangeFileInput();
onChangeTriggered.resolve(true);
}
});
patchWithCleanup(Wysiwyg.prototype, {
async _getColorpickerTemplate() {
return weTestUtils.COLOR_PICKER_TEMPLATE;
}
});
// create and load form view
const serviceRegistry = registry.category("services");
serviceRegistry.add("upload", uploadService);
serviceRegistry.add("unsplash", unsplashService);
const serverData = {
models: this.data,
};
serverData.actions = {
1: {
id: 1,
name: "test",
res_model: "mail.compose.message",
type: "ir.actions.act_window",
views: [[false, "form"]],
},
};
serverData.views = {
"mail.compose.message,false,search": "<search></search>",
"mail.compose.message,false,form": `
<form>
<field name="body" type="html"/>
<field name="attachment_ids" widget="many2many_binary"/>
</form>`,
};
const mockRPC = (route, args) => {
if (args.method === "web_save") {
const createVals = args.args[1];
assert.ok(createVals && createVals.attachment_ids);
assert.equal(createVals.attachment_ids[0][0], 4); // link command
assert.equal(createVals.attachment_ids[0][1], 5); // on attachment id "5"
webSaveTriggered.resolve();
}
if (route === "/web_editor/attachment/add_data") {
const attachment = {
id: 5,
name: "test.jpg",
description: false,
mimetype: "image/jpeg",
checksum: "7951a43bbfb08fd742224ada280913d1897b89ab",
url: false,
type: "binary",
res_id: 0,
res_model: "mail.compose.message",
public: false,
access_token: false,
image_src: "/web/image/1-a0e63e61/test.jpg",
image_width: 1,
image_height: 1,
original_id: false,
};
serverData.models['ir.attachment'].records.push({...attachment});
return Promise.resolve(attachment);
} else if (route === "/web/dataset/call_kw/ir.attachment/generate_access_token") {
return Promise.resolve(["129a52e1-6bf2-470a-830e-8e368b022e13"]);
}
};
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
//trigger wysiwyg mediadialog
const fixture = getFixture();
const formField = fixture.querySelector('.o_field_html[name="body"]');
const textInput = formField.querySelector('.note-editable p');
textInput.innerText = "test";
const pText = $(textInput).contents()[0];
Wysiwyg.setRange(pText, 1, pText, 2);
await new Promise((resolve) => setTimeout(resolve)); //ensure fully set up
const wysiwyg = $(textInput.parentElement).data('wysiwyg');
wysiwyg.openMediaDialog();
assert.ok(await Promise.race([defFileSelector, new Promise((res, _) => setTimeout(() => res(false), 400))]), "File Selector did not mount");
// upload test
const fileInputs = document.querySelectorAll(".o_select_media_dialog input.d-none.o_file_input");
const fileB64 = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigD//2Q==';
const fileBytes = new Uint8Array(atob(fileB64).split('').map(char => char.charCodeAt(0)));
// redefine 'files' so we can put mock data in through js
fileInputs.forEach((input) => Object.defineProperty(input, 'files', {
value: [new File(fileBytes, "test.jpg", { type: 'image/jpeg' })],
}));
fileInputs.forEach(input => {
input.dispatchEvent(new Event('change', {}));
});
assert.ok(await Promise.race([onChangeTriggered, new Promise((res, _) => setTimeout(() => res(false), 400))]),
"File change event was not triggered");
assert.ok(await Promise.race([onAttachmentChangeTriggered, new Promise((res, _) => setTimeout(() => res(false), 400))]),
"_onAttachmentChange was not called with the new attachment, necessary for unsused upload cleanup on backend");
// wait to check that dom is properly updated
await new Promise((res, _) => setTimeout(() => res(false), 400));
assert.ok(fixture.querySelector('.o_attachment[title="test.jpg"]'));
await click(".o_form_button_save");
await webSaveTriggered;
});
});
@@ -1,14 +1,18 @@
/** @odoo-module **/
import { click, editInput, getFixture, makeDeferred, mockSendBeacon, nextTick, patchWithCleanup } from "@web/../tests/helpers/utils";
import { createWebClient, doAction } from "@web/../tests/webclient/helpers";
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
import { FileSelectorControlPanel } from "@web_editor/components/media_dialog/file_selector";
import { FormController } from '@web/views/form/form_controller';
import { HtmlField } from "@web_editor/js/backend/html_field";
import { MediaDialog } from "@web_editor/components/media_dialog/media_dialog";
import { parseHTML, setSelection } from "@web_editor/js/editor/odoo-editor/src/utils/utils";
import { onRendered } from "@odoo/owl";
import { wysiwygData } from "@web_editor/../tests/test_utils";
import { onRendered, useEffect } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { COLOR_PICKER_TEMPLATE, wysiwygData } from "@web_editor/../tests/test_utils";
import { OdooEditor } from '@web_editor/js/editor/odoo-editor/src/OdooEditor';
import { uploadService } from "@web_editor/components/upload_progress_toast/upload_service";
import { Wysiwyg } from "@web_editor/js/wysiwyg/wysiwyg";
import { insertText } from '@web_editor/js/editor/odoo-editor/test/utils';
@@ -1056,3 +1060,194 @@ QUnit.module("WebEditor.HtmlField", ({ beforeEach }) => {
});
});
export const mediaDialogServices = {
upload: uploadService,
};
export const uploadTestModule = QUnit.module(
"WebEditor.HtmlField.upload",
{
beforeEach: function () {
this.data = wysiwygData({
"mail.compose.message": {
fields: {
display_name: {
string: "Displayed name",
type: "char",
},
body: {
string: "Message Body inline (to send)",
type: "html",
},
attachment_ids: {
string: "Attachments",
type: "many2many",
relation: "ir.attachment",
},
},
records: [
{
id: 1,
display_name: "Some Composer",
body: "Hello",
attachment_ids: [],
},
],
},
});
},
},
function () {
QUnit.test("media dialog: upload", async function (assert) {
assert.expect(7);
const onAttachmentChangeTriggered = makeDeferred();
patchWithCleanup(HtmlField.prototype, {
_onAttachmentChange(event) {
super._onAttachmentChange(event);
onAttachmentChangeTriggered.resolve(true);
},
});
const defFileSelector = makeDeferred();
const onChangeTriggered = makeDeferred();
const webSaveTriggered = makeDeferred();
patchWithCleanup(FileSelectorControlPanel.prototype, {
setup() {
super.setup();
useEffect(
() => {
defFileSelector.resolve(true);
},
() => [],
);
},
async onChangeFileInput() {
super.onChangeFileInput();
onChangeTriggered.resolve(true);
},
});
patchWithCleanup(Wysiwyg.prototype, {
async _getColorpickerTemplate() {
return COLOR_PICKER_TEMPLATE;
},
});
// create and load form view
const serviceRegistry = registry.category("services");
for (const [serviceName, serviceDefinition] of Object.entries(mediaDialogServices)) {
serviceRegistry.add(serviceName, serviceDefinition);
}
const serverData = {
models: this.data,
};
serverData.actions = {
1: {
id: 1,
name: "test",
res_model: "mail.compose.message",
type: "ir.actions.act_window",
views: [[false, "form"]],
},
};
serverData.views = {
"mail.compose.message,false,search": "<search></search>",
"mail.compose.message,false,form": `
<form>
<field name="body" type="html"/>
<field name="attachment_ids" widget="many2many_binary"/>
</form>`,
};
const mockRPC = (route, args) => {
if (args.method === "web_save") {
const createVals = args.args[1];
assert.ok(createVals && createVals.attachment_ids);
assert.equal(createVals.attachment_ids[0][0], 4); // link command
assert.equal(createVals.attachment_ids[0][1], 5); // on attachment id "5"
webSaveTriggered.resolve();
}
if (route === "/web_editor/attachment/add_data") {
const attachment = {
id: 5,
name: "test.jpg",
description: false,
mimetype: "image/jpeg",
checksum: "7951a43bbfb08fd742224ada280913d1897b89ab",
url: false,
type: "binary",
res_id: 0,
res_model: "mail.compose.message",
public: false,
access_token: false,
image_src: "/web/image/1-a0e63e61/test.jpg",
image_width: 1,
image_height: 1,
original_id: false,
};
serverData.models["ir.attachment"].records.push({ ...attachment });
return Promise.resolve(attachment);
} else if (route === "/web/dataset/call_kw/ir.attachment/generate_access_token") {
return Promise.resolve(["129a52e1-6bf2-470a-830e-8e368b022e13"]);
}
};
const webClient = await createWebClient({ serverData, mockRPC });
await doAction(webClient, 1);
//trigger wysiwyg mediadialog
const fixture = getFixture();
const formField = fixture.querySelector('.o_field_html[name="body"]');
const textInput = formField.querySelector(".note-editable p");
textInput.innerText = "test";
const pText = $(textInput).contents()[0];
Wysiwyg.setRange(pText, 1, pText, 2);
await new Promise((resolve) => setTimeout(resolve)); //ensure fully set up
const wysiwyg = $(textInput.parentElement).data("wysiwyg");
wysiwyg.openMediaDialog();
assert.ok(
await Promise.race([
defFileSelector,
new Promise((res, _) => setTimeout(() => res(false), 400)),
]),
"File Selector did not mount",
);
// upload test
const fileInputs = document.querySelectorAll(
".o_select_media_dialog input.d-none.o_file_input",
);
const fileB64 =
"/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigD//2Q==";
const fileBytes = new Uint8Array(
atob(fileB64)
.split("")
.map((char) => char.charCodeAt(0)),
);
// redefine 'files' so we can put mock data in through js
fileInputs.forEach((input) =>
Object.defineProperty(input, "files", {
value: [new File(fileBytes, "test.jpg", { type: "image/jpeg" })],
}),
);
fileInputs.forEach((input) => {
input.dispatchEvent(new Event("change", {}));
});
assert.ok(
await Promise.race([
onChangeTriggered,
new Promise((res, _) => setTimeout(() => res(false), 400)),
]),
"File change event was not triggered",
);
assert.ok(
await Promise.race([
onAttachmentChangeTriggered,
new Promise((res, _) => setTimeout(() => res(false), 400)),
]),
"_onAttachmentChange was not called with the new attachment, necessary for unsused upload cleanup on backend"
);
// wait to check that dom is properly updated
await new Promise((res, _) => setTimeout(() => res(false), 400));
assert.ok(fixture.querySelector('.o_attachment[title="test.jpg"]'));
await click(fixture.querySelector(".o_form_button_save"));
await webSaveTriggered;
});
},
);
+1 -1
View File
@@ -8,7 +8,7 @@ import { Wysiwyg } from '@web_editor/js/wysiwyg/wysiwyg';
import options from "@web_editor/js/editor/snippets.options";
import { TABLE_ATTRIBUTES, TABLE_STYLES } from '@web_editor/js/backend/convert_inline';
const COLOR_PICKER_TEMPLATE = `
export const COLOR_PICKER_TEMPLATE = `
<colorpicker>
<div class="o_colorpicker_section" data-name="theme" data-display="Theme Colors" data-icon-class="fa fa-flask">
<button data-color="o-color-1"/>
+3
View File
@@ -20,6 +20,9 @@
'web_unsplash/static/src/components/media_dialog/*.xml',
'web_unsplash/static/src/services/unsplash_service.js',
],
'web.qunit_suite_tests': [
'web_unsplash/static/tests/**/*',
],
},
'license': 'LGPL-3',
}
@@ -0,0 +1,7 @@
/** @odoo-module **/
import { unsplashService } from "@web_unsplash/services/unsplash_service";
import { mediaDialogServices } from "@web_editor/../tests/html_field_tests";
// update the list of required services to open the media dialog
mediaDialogServices.unsplash = unsplashService;