mirror of
https://github.com/bringout/oca-ocb-web.git
synced 2026-04-19 02:32:09 +02:00
replace stale web_editor with html_editor and html_builder for 19.0
web_editor was removed in Odoo 19.0 and replaced by html_editor
and html_builder. The old web_editor was incorrectly included in
the 19.0 vanilla import.
🤖 assisted by claude
This commit is contained in:
parent
4b94f0abc5
commit
f866779561
1513 changed files with 396049 additions and 358525 deletions
|
|
@ -0,0 +1,131 @@
|
|||
import { expect, test } from "@odoo/hoot";
|
||||
import { markup } from "@odoo/owl";
|
||||
import { setupEditor, testEditor } from "./_helpers/editor";
|
||||
import { fixInvalidHTML } from "@html_editor/utils/sanitize";
|
||||
|
||||
const Markup = markup().constructor;
|
||||
|
||||
test("sanitize should remove nasty elements", async () => {
|
||||
const { editor } = await setupEditor("");
|
||||
expect(editor.shared.sanitize.sanitize("<img src=x onerror=alert(1)//>")).toBe('<img src="x">');
|
||||
expect(editor.shared.sanitize.sanitize("<svg><g/onload=alert(2)//<p>")).toBe(
|
||||
"<svg><g></g></svg>"
|
||||
);
|
||||
expect(
|
||||
editor.shared.sanitize.sanitize("<p>abc<iframe//src=jAva	script:alert(3)>def</p>")
|
||||
).toBe("<p>abc</p>");
|
||||
});
|
||||
|
||||
test("sanitize should leave t-field, t-out, t-esc as is", async () => {
|
||||
const { editor } = await setupEditor("");
|
||||
expect(editor.shared.sanitize.sanitize(`<span t-esc="expr"></span>`)).toBe(
|
||||
'<span t-esc="expr"></span>'
|
||||
);
|
||||
expect(editor.shared.sanitize.sanitize(`<span t-out="expr"></span>`)).toBe(
|
||||
'<span t-out="expr"></span>'
|
||||
);
|
||||
expect(editor.shared.sanitize.sanitize(`<span t-field="expr"></span>`)).toBe(
|
||||
'<span t-field="expr"></span>'
|
||||
);
|
||||
});
|
||||
|
||||
test("sanitize plugin should handle contenteditable attribute with o-contenteditable-[true/false] class", async () => {
|
||||
await testEditor({
|
||||
contentBefore: `<p class="o-contenteditable-true">a[]</p><p class="o-contenteditable-false">b</p>`,
|
||||
contentAfterEdit: `<p class="o-contenteditable-true" contenteditable="true">a[]</p><p class="o-contenteditable-false" contenteditable="false">b</p>`,
|
||||
contentAfter: `<p class="o-contenteditable-true">a[]</p><p class="o-contenteditable-false">b</p>`,
|
||||
});
|
||||
});
|
||||
|
||||
test("sanitize plugin should handle role attribute with data-oe-role attribute", async () => {
|
||||
await testEditor({
|
||||
contentBefore: `<p data-oe-role="status">a[]</p>`,
|
||||
contentAfterEdit: `<p data-oe-role="status" role="status">a[]</p>`,
|
||||
contentAfter: `<p data-oe-role="status">a[]</p>`,
|
||||
});
|
||||
});
|
||||
|
||||
test("sanitize plugin should handle aria-label attribute with data-oe-aria-label attribute", async () => {
|
||||
await testEditor({
|
||||
contentBefore: `<p data-oe-aria-label="status">a[]</p>`,
|
||||
contentAfterEdit: `<p data-oe-aria-label="status" aria-label="status">a[]</p>`,
|
||||
contentAfter: `<p data-oe-aria-label="status">a[]</p>`,
|
||||
});
|
||||
});
|
||||
|
||||
test("fixInvalidHTML should close self-closing elements", () => {
|
||||
expect(fixInvalidHTML(markup`<t/>`).toString()).toBe("<t></t>");
|
||||
expect(fixInvalidHTML(markup`<t class="test"/>`).toString()).toBe('<t class="test"></t>');
|
||||
expect(fixInvalidHTML(markup`<a/>`).toString()).toBe("<a></a>");
|
||||
expect(fixInvalidHTML(markup`<a href="#"/>`).toString()).toBe('<a href="#"></a>');
|
||||
expect(fixInvalidHTML(markup`<strong/>`).toString()).toBe("<strong></strong>");
|
||||
expect(fixInvalidHTML(markup`<strong class="bold"/>`).toString()).toBe(
|
||||
'<strong class="bold"></strong>'
|
||||
);
|
||||
expect(fixInvalidHTML(markup`<span/>`).toString()).toBe("<span></span>");
|
||||
expect(fixInvalidHTML(markup`<span id="test"/>`).toString()).toBe('<span id="test"></span>');
|
||||
expect(
|
||||
fixInvalidHTML(
|
||||
markup`<t t-out="object.name"/>asdf<t t-out="object.parner_id.name"/>`
|
||||
).toString()
|
||||
).toBe('<t t-out="object.name"></t>asdf<t t-out="object.parner_id.name"></t>');
|
||||
});
|
||||
|
||||
test("fixInvalidHTML escapes string input", () => {
|
||||
expect(fixInvalidHTML("<t/>").toString()).toBe("<t/>");
|
||||
expect(fixInvalidHTML('<a href="?param=value&other=test"/>').toString()).toBe(
|
||||
"<a href="?param=value&other=test"/>"
|
||||
);
|
||||
});
|
||||
|
||||
test("fixInvalidHTML should return markup", () => {
|
||||
expect(fixInvalidHTML(markup`<t/>`)).toBeInstanceOf(Markup);
|
||||
expect(fixInvalidHTML("<t/>")).toBeInstanceOf(Markup);
|
||||
});
|
||||
|
||||
test("fixInvalidHTML handles nested self-closing tags correctly", () => {
|
||||
expect(fixInvalidHTML(markup`<t><t/><t><t/></t></t>`).toString()).toBe(
|
||||
"<t><t></t><t><t></t></t></t>"
|
||||
);
|
||||
expect(fixInvalidHTML(markup`<span><span class="inner"/></span>`).toString()).toBe(
|
||||
'<span><span class="inner"></span></span>'
|
||||
);
|
||||
});
|
||||
|
||||
test("fixInvalidHTML preserves escaped content in attributes and text", () => {
|
||||
expect(fixInvalidHTML(markup`<span title="quoted & special"/>`).toString()).toBe(
|
||||
`<span title="quoted & special"></span>`
|
||||
);
|
||||
expect(fixInvalidHTML(markup`<p>Text with <escaped> content</p>`).toString()).toBe(
|
||||
`<p>Text with <escaped> content</p>`
|
||||
);
|
||||
});
|
||||
|
||||
test("fixInvalidHTML attribute", () => {
|
||||
// Properly quoted attributes should work
|
||||
expect(fixInvalidHTML(markup`<t onclick="alert('test')"/>`).toString()).toBe(
|
||||
`<t onclick="alert('test')"></t>`
|
||||
);
|
||||
|
||||
// Unclosed quotes should NOT be converted (security protection)
|
||||
expect(fixInvalidHTML(markup`<t class="unclosed/>`).toString()).toBe(`<t class="unclosed/>`);
|
||||
|
||||
// Mismatched quotes should NOT be converted (security protection)
|
||||
expect(fixInvalidHTML(markup`<t class="test'/>`).toString()).toBe(`<t class="test'/>`);
|
||||
|
||||
// Valid data attributes with special characters should work
|
||||
expect(fixInvalidHTML(markup`<span data-config='{"key": "value"}'/>`).toString()).toBe(
|
||||
`<span data-config='{"key": "value"}'></span>`
|
||||
);
|
||||
|
||||
// Attributes with invalid characters in unquoted values should NOT match
|
||||
expect(fixInvalidHTML(markup`<t class=test>value/>`).toString()).toBe(`<t class=test>value/>`);
|
||||
|
||||
// Attributes containing < or > characters in quoted values should work
|
||||
expect(fixInvalidHTML(markup`<t data-rule="value < 10"/>`).toString()).toBe(
|
||||
`<t data-rule="value < 10"></t>`
|
||||
);
|
||||
expect(fixInvalidHTML(markup`<span title="score > 100"/>`).toString()).toBe(
|
||||
`<span title="score > 100"></span>`
|
||||
);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue