Add JavaScript tests.
Run "npm install", then "npm test".
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
// XxxEditor.parse() and XxxEditor.serialize(): the HTML that the editor keeps and writes
|
||||
"use strict";
|
||||
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { load } = require("./helpers");
|
||||
|
||||
const window = load(["publish/editor.js"], "");
|
||||
const { parse, serialize } = window.XxxEditor;
|
||||
|
||||
// The HTML that the editor writes for *html*
|
||||
function clean(html) {
|
||||
const holder = window.document.createElement("div");
|
||||
holder.appendChild(parse(html));
|
||||
return serialize(holder);
|
||||
}
|
||||
|
||||
test("simple paragraphs stay the same", () => {
|
||||
assert.equal(clean("<p>One</p>\n<p>Two <strong>bold</strong> <em>it</em> <u>u</u> x<sup>2</sup> H<sub>2</sub>O</p>"),
|
||||
"<p>One</p>\n<p>Two <strong>bold</strong> <em>it</em> <u>u</u> x<sup>2</sup> H<sub>2</sub>O</p>");
|
||||
});
|
||||
|
||||
test("b and i become strong and em", () => {
|
||||
assert.equal(clean("<p><b>b</b> <i>i</i></p>"), "<p><strong>b</strong> <em>i</em></p>");
|
||||
});
|
||||
|
||||
test("scripts, styles and frames are dropped with their contents", () => {
|
||||
assert.equal(clean("<p>a<script>alert(1)</script>b</p><style>p{}</style><iframe src='x'></iframe>"), "<p>ab</p>");
|
||||
});
|
||||
|
||||
test("event handlers and unknown attributes are dropped", () => {
|
||||
assert.equal(clean('<p onclick="x()" class="c" id="i">a</p><img src="x" onerror="alert(1)">'), "<p>a</p>");
|
||||
});
|
||||
|
||||
test("unknown tags keep their contents", () => {
|
||||
assert.equal(clean("<p><font color='red'>red</font> <span>plain</span></p>"), "<p>red plain</p>");
|
||||
});
|
||||
|
||||
test("headings become paragraphs", () => {
|
||||
assert.equal(clean("<h2>Title</h2>"), "<p>Title</p>");
|
||||
});
|
||||
|
||||
test("only safe links are kept", () => {
|
||||
assert.equal(clean('<p><a href="https://example.org/?a=1&b=2" title="T "q"">x</a></p>'),
|
||||
'<p><a href="https://example.org/?a=1&b=2" title="T "q"">x</a></p>');
|
||||
assert.equal(clean('<p><a href="mailto:a@example.org">m</a> <a href="/about">r</a> <a href="#top">h</a></p>'),
|
||||
'<p><a href="mailto:a@example.org">m</a> <a href="/about">r</a> <a href="#top">h</a></p>');
|
||||
assert.equal(clean('<p><a href="javascript:alert(1)">x</a></p>'), "<p><a>x</a></p>");
|
||||
assert.equal(clean('<p><a href=" JaVaScRiPt:alert(1)">x</a></p>'), "<p><a>x</a></p>");
|
||||
assert.equal(clean('<p><a href="data:text/html,x">x</a></p>'), "<p><a>x</a></p>");
|
||||
});
|
||||
|
||||
test("only alignment and indent styles are kept", () => {
|
||||
assert.equal(clean('<p style="text-align: center; color: red">c</p>'), '<p style="text-align: center;">c</p>');
|
||||
assert.equal(clean('<p style="padding-left: 30px">i</p>'), '<p style="padding-left: 30px;">i</p>');
|
||||
assert.equal(clean('<p style="margin-left: expression(alert(1))">x</p>'), "<p>x</p>");
|
||||
assert.equal(clean('<p><span style="color: red">x</span></p>'), "<p>x</p>");
|
||||
assert.equal(clean('<p><span style="text-align: right">x</span></p>'), '<p><span style="text-align: right;">x</span></p>');
|
||||
});
|
||||
|
||||
test("the align attribute is kept only with a real alignment", () => {
|
||||
assert.equal(clean('<p align="center">c</p>'), '<p align="center">c</p>');
|
||||
assert.equal(clean('<p align="evil">c</p>'), "<p>c</p>");
|
||||
});
|
||||
|
||||
test("text is escaped", () => {
|
||||
assert.equal(clean("<p>a < b & c > d \"q\"</p>"), "<p>a < b & c > d \"q\"</p>");
|
||||
});
|
||||
|
||||
test("line breaks, rules and no-break spaces are written as TinyMCE wrote them", () => {
|
||||
assert.equal(clean("<p>one<br>two</p><hr><p>a b</p>"), "<p>one<br />two</p>\n<hr />\n<p>a b</p>");
|
||||
});
|
||||
|
||||
test("an empty paragraph is written as ", () => {
|
||||
assert.equal(clean("<p>a</p><p></p><p><br></p><p>b</p>"), "<p>a</p>\n<p> </p>\n<p> </p>\n<p>b</p>");
|
||||
});
|
||||
|
||||
test("a trailing line break in a block is dropped", () => {
|
||||
assert.equal(clean("<p>a<br></p>"), "<p>a</p>");
|
||||
});
|
||||
|
||||
test("an editor with no words gives an empty story", () => {
|
||||
assert.equal(clean(""), "");
|
||||
assert.equal(clean("<p><br></p>"), "");
|
||||
assert.equal(clean("<p> </p><p></p>"), "");
|
||||
assert.equal(clean("<hr>"), "<hr />");
|
||||
});
|
||||
|
||||
test("blockquotes and lists put their blocks on new lines", () => {
|
||||
assert.equal(clean("<blockquote><p>q</p></blockquote>"), "<blockquote>\n<p>q</p>\n</blockquote>");
|
||||
assert.equal(clean("<ul><li>a</li><li>b</li></ul><ol><li>c</li></ol>"), "<ul>\n<li>a</li>\n<li>b</li>\n</ul>\n<ol>\n<li>c</li>\n</ol>");
|
||||
});
|
||||
|
||||
test("whitespace between blocks is dropped", () => {
|
||||
assert.equal(clean("<p>a</p>\n\n <p>b</p>"), "<p>a</p>\n<p>b</p>");
|
||||
});
|
||||
|
||||
test("parse does not run anything", () => {
|
||||
window.hacked = false;
|
||||
parse('<img src="x" onerror="window.hacked = true"><script>window.hacked = true</script>');
|
||||
assert.equal(window.hacked, false);
|
||||
});
|
||||
Reference in New Issue
Block a user