Revert merge request GNOME/geary!374 for now since the shared process model breaks old-style WebProcess message handler IPC. This can be un-reverted when out JS is ported to the new Messages API that is landing in WebKitGTK 2.28. This reverts commite4a5b85698, reversing changes made to66f6525480.
438 lines
16 KiB
Vala
438 lines
16 KiB
Vala
/*
|
||
* Copyright 2016 Michael Gratton <mike@vee.net>
|
||
*
|
||
* This software is licensed under the GNU Lesser General Public License
|
||
* (version 2.1 or later). See the COPYING file in this distribution.
|
||
*/
|
||
|
||
class Composer.PageStateTest : ClientWebViewTestCase<Composer.WebView> {
|
||
|
||
public const string COMPLETE_BODY_TEMPLATE =
|
||
"""<div id="geary-body" dir="auto">%s<div><br></div><div><br></div></div><div id="geary-signature" dir="auto"></div>""";
|
||
public const string DIRTY_BODY_TEMPLATE =
|
||
"""
|
||
<div id="geary-body" dir="auto" class="geary-focus" contenteditable="true">%s<div><br></div><div><br></div></div>
|
||
<div id="geary-signature" class="geary-no-display" dir="auto" contenteditable="true"></div>
|
||
""";
|
||
public const string CLEAN_BODY_TEMPLATE = """<div id="geary-body" dir="auto">%s<div><br></div><div><br></div></div>""";
|
||
|
||
public PageStateTest() {
|
||
base("Composer.PageStateTest");
|
||
add_test("html_to_text", html_to_text);
|
||
add_test("html_to_text_with_quote", html_to_text_with_quote);
|
||
add_test("html_to_text_with_nested_quote", html_to_text_with_nested_quote);
|
||
add_test("html_to_text_with_blacklist", html_to_text_with_blacklist);
|
||
add_test("edit_context_font", edit_context_font);
|
||
add_test("edit_context_link", edit_context_link);
|
||
add_test("indent_line", indent_line);
|
||
add_test("clean_content", clean_content);
|
||
add_test("get_html", get_html);
|
||
add_test("get_text", get_text);
|
||
add_test("contains_keywords", contains_keywords);
|
||
// Depends contains_keywords and html_to_text_with_blacklist
|
||
add_test("contains_attachment_keywords", contains_attachment_keywords);
|
||
add_test("replace_non_breaking_space", replace_non_breaking_space);
|
||
|
||
try {
|
||
WebView.load_resources();
|
||
} catch (Error err) {
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void html_to_text() throws Error {
|
||
load_body_fixture("<p>para</p>");
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(
|
||
@"ComposerPageState.htmlToText(window.document.body);"
|
||
).get_js_value()
|
||
) == "para\n\n\n\n"
|
||
);
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void html_to_text_with_quote() throws Error {
|
||
unichar q_marker = Geary.RFC822.Utils.QUOTE_MARKER;
|
||
load_body_fixture("<p>pre</p> <blockquote><p>quote</p></blockquote> <p>post</p>");
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(
|
||
"ComposerPageState.htmlToText(window.document.body);"
|
||
).get_js_value()
|
||
) == @"pre\n\n$(q_marker)quote\n$(q_marker)\npost\n\n\n\n"
|
||
);
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void html_to_text_with_nested_quote() throws Error {
|
||
unichar q_marker = Geary.RFC822.Utils.QUOTE_MARKER;
|
||
load_body_fixture("<p>pre</p> <blockquote><p>quote1</p> <blockquote><p>quote2</p></blockquote></blockquote> <p>post</p>");
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(
|
||
"ComposerPageState.htmlToText(window.document.body)"
|
||
).get_js_value()
|
||
) == @"pre\n\n$(q_marker)quote1\n$(q_marker)\n$(q_marker)$(q_marker)quote2\n$(q_marker)$(q_marker)\npost\n\n\n\n"
|
||
);
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void html_to_text_with_blacklist() throws Error {
|
||
load_body_fixture("<p>pre</p> <blockquote><p>quote1</p> <blockquote><p>quote2</p></blockquote></blockquote> <p>post</p>");
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(
|
||
"ComposerPageState.htmlToText(window.document.body, [\"blockquote\"])"
|
||
).get_js_value()
|
||
) == @"pre\n\npost\n\n\n\n"
|
||
);
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void edit_context_link() throws Error {
|
||
string html = "<a id=\"test\" href=\"url\">para</a>";
|
||
load_body_fixture(html);
|
||
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(@"new EditContext(document.getElementById('test')).encode()")
|
||
.get_js_value()
|
||
).has_prefix("1;url;"));
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void edit_context_font() throws Error {
|
||
string html = "<p id=\"test\" style=\"font-family: Comic Sans; font-size: 144; color: #FF7F01\">para</p>";
|
||
load_body_fixture(html);
|
||
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(@"new EditContext(document.getElementById('test')).encode()")
|
||
.get_js_value()
|
||
) == "0;;Comic Sans;144;rgb(255, 127, 1)");
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void indent_line() throws Error {
|
||
load_body_fixture("""<span id="test">some text</span>""");
|
||
try {
|
||
run_javascript(@"SelectionUtil.selectNode(document.getElementById('test'))");
|
||
run_javascript(@"geary.indentLine()");
|
||
assert(
|
||
Util.JS.to_int32(
|
||
run_javascript(@"document.querySelectorAll('blockquote[type=cite]').length")
|
||
.get_js_value()
|
||
) == 1
|
||
);
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(@"document.querySelectorAll('blockquote[type=cite]').item(0).innerText")
|
||
.get_js_value()
|
||
) == "some text"
|
||
);
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void contains_attachment_keywords() throws Error {
|
||
load_body_fixture_full("""
|
||
<blockquote>innerquote</blockquote>
|
||
|
||
<p>some text</p>
|
||
|
||
some text
|
||
""",
|
||
"<p>outerquote text</p>",
|
||
true
|
||
);
|
||
try {
|
||
assert(
|
||
Util.JS.to_bool(
|
||
run_javascript(@"geary.containsAttachmentKeyword(\"some\", \"subject text\");")
|
||
.get_js_value()
|
||
)
|
||
);
|
||
assert(
|
||
Util.JS.to_bool(
|
||
run_javascript(@"geary.containsAttachmentKeyword(\"subject\", \"subject text\");")
|
||
.get_js_value()
|
||
)
|
||
);
|
||
assert(
|
||
!Util.JS.to_bool(
|
||
run_javascript(@"geary.containsAttachmentKeyword(\"innerquote\", \"subject text\");")
|
||
.get_js_value()
|
||
)
|
||
);
|
||
assert(
|
||
!Util.JS.to_bool(
|
||
run_javascript(@"geary.containsAttachmentKeyword(\"outerquote\", \"subject text\");")
|
||
.get_js_value()
|
||
)
|
||
);
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void clean_content() throws Error {
|
||
// XXX split these up into multiple tests
|
||
load_body_fixture("""
|
||
http://example1.com
|
||
|
||
<p>http://example2.com</p>
|
||
|
||
<p>http://example3.com http://example4.com</p>
|
||
|
||
<a href="blarg">http://example5.com</a>
|
||
|
||
unknown://example6.com
|
||
|
||
I can send email through smtp.gmail.com:587 or through https://www.gmail.com/
|
||
""");
|
||
|
||
string expected = """
|
||
<a href="http://example1.com">http://example1.com</a>
|
||
|
||
<p><a href="http://example2.com">http://example2.com</a></p>
|
||
|
||
<p><a href="http://example3.com">http://example3.com</a> <a href="http://example4.com">http://example4.com</a></p>
|
||
|
||
<a href="blarg">http://example5.com</a>
|
||
|
||
unknown://example6.com
|
||
|
||
I can send email through smtp.gmail.com:587 or through <a href="https://www.gmail.com/">https://www.gmail.com/</a>
|
||
""";
|
||
|
||
try {
|
||
run_javascript("geary.cleanContent();");
|
||
string result = Util.JS.to_string(
|
||
run_javascript("window.document.body.innerHTML;")
|
||
.get_js_value()
|
||
);
|
||
assert(result == DIRTY_BODY_TEMPLATE.printf(expected));
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void get_html() throws Error {
|
||
string html = "<p>para</p>";
|
||
load_body_fixture(html);
|
||
try {
|
||
string result = Util.JS.to_string(
|
||
run_javascript(@"window.geary.getHtml();").get_js_value()
|
||
);
|
||
assert(result == CLEAN_BODY_TEMPLATE.printf(html));
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void get_text() throws Error {
|
||
load_body_fixture("<p>para</p>");
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(@"window.geary.getText();")
|
||
.get_js_value()
|
||
) == "para\n\n\n\n"
|
||
);
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void contains_keywords() throws Error {
|
||
load_body_fixture();
|
||
string complete_keys = """new Set(["keyword1", "keyword2"])""";
|
||
string suffix_keys = """new Set(["sf1", "sf2"])""";
|
||
try {
|
||
// Doesn't contain
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('notcontained', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('not contained', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('not\tcontained', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('http://www.keyword1.com', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('http://www.something.com/something.sf1', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('sf1', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('.sf1', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
|
||
// Does contain
|
||
assert(Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('keyword1', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('keyword2 contained', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('keyword2\tcontained', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('keyword1.', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('something.sf1', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('something.something.sf2', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
assert(!Util.JS.to_bool(run_javascript(
|
||
@"ComposerPageState.containsKeywords('http://something/esle.sf2', $complete_keys, $suffix_keys);"
|
||
).get_js_value()
|
||
));
|
||
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
public void replace_non_breaking_space() throws Error {
|
||
load_body_fixture();
|
||
string single_nbsp = "a b";
|
||
string multiple_nbsp = "a b c";
|
||
try {
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(@"ComposerPageState.replaceNonBreakingSpace('$(single_nbsp)');")
|
||
.get_js_value()
|
||
) == "a b");
|
||
assert(
|
||
Util.JS.to_string(
|
||
run_javascript(@"ComposerPageState.replaceNonBreakingSpace('$(multiple_nbsp)');")
|
||
.get_js_value()
|
||
) == "a b c");
|
||
} catch (Util.JS.Error err) {
|
||
print("Util.JS.Error: %s\n", err.message);
|
||
assert_not_reached();
|
||
} catch (Error err) {
|
||
print("WKError: %s\n", err.message);
|
||
assert_not_reached();
|
||
}
|
||
}
|
||
|
||
protected override Composer.WebView set_up_test_view() {
|
||
return new Composer.WebView(this.config);
|
||
}
|
||
|
||
protected override void load_body_fixture(string body = "") {
|
||
load_body_fixture_full(body, "", true);
|
||
}
|
||
|
||
protected void load_body_fixture_full(string body,
|
||
string quote,
|
||
bool top_posting) {
|
||
this.test_view.load_html(body, quote, top_posting, false);
|
||
while (this.test_view.is_loading) {
|
||
Gtk.main_iteration();
|
||
}
|
||
}
|
||
|
||
}
|