summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/mime/test/unit/test_structured_headers.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/mime/test/unit/test_structured_headers.js')
-rw-r--r--comm/mailnews/mime/test/unit/test_structured_headers.js249
1 files changed, 249 insertions, 0 deletions
diff --git a/comm/mailnews/mime/test/unit/test_structured_headers.js b/comm/mailnews/mime/test/unit/test_structured_headers.js
new file mode 100644
index 0000000000..aedc70ac59
--- /dev/null
+++ b/comm/mailnews/mime/test/unit/test_structured_headers.js
@@ -0,0 +1,249 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This tests the msgIStructuredHeaders and msgIWritableStructuredHeaders
+// interfaces.
+
+// Verify that a specific XPCOM error code is thrown.
+function verifyError(block, errorCode) {
+ let caught = undefined;
+ try {
+ block();
+ } catch (actual) {
+ caught = actual.result;
+ }
+ Assert.equal(caught, errorCode);
+}
+
+var StructuredHeaders = CC(
+ "@mozilla.org/messenger/structuredheaders;1",
+ Ci.msgIWritableStructuredHeaders
+);
+
+add_task(async function check_addressing() {
+ let headers = new StructuredHeaders();
+ headers.setHeader("To", [{ name: "undisclosed-recipients", group: [] }]);
+ Assert.ok(Array.isArray(headers.getHeader("To")));
+ let flat = headers.getAddressingHeader("To", false);
+ Assert.ok(Array.isArray(flat));
+ Assert.equal(flat.length, 0);
+ let full = headers.getAddressingHeader("To", true);
+ Assert.ok(Array.isArray(full));
+ Assert.equal(full.length, 1);
+ Assert.equal(full[0].name, "undisclosed-recipients");
+ Assert.ok(Array.isArray(full[0].group));
+ Assert.equal(headers.getRawHeader("To"), "undisclosed-recipients: ;");
+
+ headers.setHeader("To", [{ name: "\u00D3", email: "test@foo.invalid" }]);
+ Assert.equal(
+ headers.getRawHeader("To"),
+ "=?UTF-8?B?w5M=?= <test@foo.invalid>"
+ );
+ headers.setAddressingHeader("To", [
+ { name: "Comma, Name", email: "test@foo.invalid" },
+ ]);
+ Assert.equal(headers.getRawHeader("To"), '"Comma, Name" <test@foo.invalid>');
+});
+
+add_task(async function check_custom_header() {
+ // Load an extension for our custom header.
+ let url = Services.io.newFileURI(do_get_file("custom_header.js")).spec;
+ let promise = new Promise((resolve, reject) => {
+ function observer(subject, topic, data) {
+ Assert.equal(topic, "xpcom-category-entry-added");
+ Assert.equal(data, "custom-mime-encoder");
+ resolve();
+ Services.obs.removeObserver(observer, "xpcom-category-entry-added");
+ }
+ Services.obs.addObserver(observer, "xpcom-category-entry-added");
+ });
+ Services.catMan.addCategoryEntry(
+ "custom-mime-encoder",
+ "X-Unusual",
+ url,
+ false,
+ true
+ );
+ // The category manager doesn't fire until a later timestep.
+ await promise;
+ let headers = new StructuredHeaders();
+ headers.setRawHeader("X-Unusual", "10");
+ Assert.equal(headers.getHeader("X-Unusual"), 16);
+ headers.setHeader("X-Unusual", 32);
+ Assert.equal(headers.getRawHeader("X-Unusual"), "20");
+});
+
+add_task(async function check_raw() {
+ let headers = new StructuredHeaders();
+ Assert.ok(!headers.hasHeader("Date"));
+ let day = new Date("2000-01-01T00:00:00Z");
+ headers.setHeader("Date", day);
+ Assert.ok(headers.hasHeader("Date"));
+ Assert.ok(headers.hasHeader("date"));
+ Assert.equal(headers.getHeader("Date"), day);
+ Assert.equal(headers.getHeader("date"), day);
+ verifyError(
+ () => headers.getUnstructuredHeader("Date"),
+ Cr.NS_ERROR_ILLEGAL_VALUE
+ );
+ verifyError(
+ () => headers.getAddressingHeader("Date"),
+ Cr.NS_ERROR_ILLEGAL_VALUE
+ );
+ // This is easier than trying to match the actual value for the Date header,
+ // since that depends on the current timezone.
+ Assert.equal(new Date(headers.getRawHeader("Date")).getTime(), day.getTime());
+
+ // Otherwise, the string values should work.
+ headers.setRawHeader("Custom-Date", "1 Jan 2000 00:00:00 +0000");
+ Assert.equal(
+ headers.getRawHeader("Custom-Date"),
+ "1 Jan 2000 00:00:00 +0000"
+ );
+ headers.deleteHeader("Custom-Date");
+
+ headers.setUnstructuredHeader("Content-Description", "A description!");
+ Assert.equal(headers.getHeader("Content-Description"), "A description!");
+ Assert.equal(
+ headers.getUnstructuredHeader("Content-Description"),
+ "A description!"
+ );
+ verifyError(
+ () => headers.getAddressingHeader("Content-Description"),
+ Cr.NS_ERROR_ILLEGAL_VALUE
+ );
+ Assert.equal(headers.getRawHeader("Content-Description"), "A description!");
+
+ Assert.ok(!headers.hasHeader("Subject"));
+ Assert.ok(headers.getUnstructuredHeader("Subject") === null);
+ headers.setRawHeader("Subject", "=?UTF-8?B?56eB44Gv5Lu25ZCN5Y2I5YmN?=");
+ Assert.equal(
+ headers.getHeader("Subject"),
+ "\u79c1\u306f\u4ef6\u540d\u5348\u524d"
+ );
+ Assert.equal(
+ headers.getRawHeader("Subject"),
+ "=?UTF-8?B?56eB44Gv5Lu25ZCN5Y2I5YmN?="
+ );
+
+ // Multiple found headers
+ Assert.equal(headers.getHeader("Not-Found-Anywhere"), undefined);
+ Assert.notEqual(headers.getHeader("Not-Found-Anywhere"), "");
+ Assert.equal(headers.getRawHeader("Not-Found-Anywhere"), undefined);
+ headers.setHeader("Not-Found-Anywhere", 515);
+ Assert.equal(headers.getHeader("Not-Found-Anywhere"), 515);
+ headers.deleteHeader("not-found-anywhere");
+ Assert.equal(headers.getHeader("Not-Found-Anywhere"), undefined);
+
+ // Check the enumeration of header values.
+ headers.setHeader("unabashed-random-header", false);
+ let headerList = [
+ "Date",
+ "Content-Description",
+ "Subject",
+ "Unabashed-Random-Header",
+ ];
+ for (let value of headers.headerNames) {
+ Assert.equal(value.toLowerCase(), headerList.shift().toLowerCase());
+ }
+
+ // Check that copying works
+ let moreHeaders = new StructuredHeaders();
+ moreHeaders.addAllHeaders(headers);
+ for (let value of headers.headerNames) {
+ Assert.equal(moreHeaders.getHeader(value), headers.getHeader(value));
+ }
+ headers.deleteHeader("Date");
+ Assert.ok(moreHeaders.hasHeader("Date"));
+});
+
+add_task(async function check_nsIMimeHeaders() {
+ let headers = Cc["@mozilla.org/messenger/mimeheaders;1"].createInstance(
+ Ci.nsIMimeHeaders
+ );
+ Assert.ok(headers instanceof Ci.msgIStructuredHeaders);
+ Assert.equal(false, headers instanceof Ci.msgIWritableStructuredHeaders);
+ headers.initialize(
+ mailTestUtils.loadFileToString(do_get_file("../../../data/draft1"))
+ );
+ Assert.equal(headers.getHeader("To").length, 1);
+ Assert.equal(headers.getHeader("To")[0].email, "bugmail@example.org");
+ Assert.equal(headers.getAddressingHeader("To").length, 1);
+ Assert.equal(headers.getHeader("Content-Type").type, "text/html");
+
+ let headerList = [
+ "X-Mozilla-Status",
+ "X-Mozilla-Status2",
+ "X-Mozilla-Keys",
+ "FCC",
+ "BCC",
+ "X-Identity-Key",
+ "Message-ID",
+ "Date",
+ "From",
+ "X-Mozilla-Draft-Info",
+ "User-Agent",
+ "MIME-Version",
+ "To",
+ "Subject",
+ "Content-Type",
+ "Content-Transfer-Encoding",
+ ];
+ for (let value of headers.headerNames) {
+ Assert.equal(value.toLowerCase(), headerList.shift().toLowerCase());
+ }
+});
+
+add_task(async function checkBuildMimeText() {
+ let headers = new StructuredHeaders();
+ headers.setHeader("To", [
+ { name: "François Smith", email: "user@☃.invalid" },
+ ]);
+ headers.setHeader("From", [{ name: "John Doe", email: "jdoe@test.invalid" }]);
+ headers.setHeader(
+ "Subject",
+ "A subject that spans a distance quite in " +
+ "excess of 80 characters so as to force an intermediary CRLF"
+ );
+ headers.setHeader(
+ "User-Agent",
+ "Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101 Thunderbird/40.0a1"
+ );
+ let mimeText =
+ "To: =?UTF-8?Q?Fran=C3=A7ois_Smith?= <user@☃.invalid>\r\n" +
+ "From: John Doe <jdoe@test.invalid>\r\n" +
+ "Subject: A subject that spans a distance quite in excess of 80 characters so\r\n" +
+ " as to force an intermediary CRLF\r\n" +
+ "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:40.0) Gecko/20100101\r\n" +
+ " Thunderbird/40.0a1\r\n";
+ Assert.equal(headers.buildMimeText(), mimeText);
+
+ // Check the version used for the nsIMimeHeaders implementation. This requires
+ // initializing with a UTF-8 version.
+ let utf8Text = mimeText.replace("☃", "\xe2\x98\x83");
+ let mimeHeaders = Cc["@mozilla.org/messenger/mimeheaders;1"].createInstance(
+ Ci.nsIMimeHeaders
+ );
+ mimeHeaders.initialize(utf8Text);
+ Assert.equal(mimeHeaders.getHeader("To")[0].email, "user@☃.invalid");
+ Assert.equal(mimeHeaders.buildMimeText(), mimeText);
+ Assert.equal(mimeHeaders.allHeaders, utf8Text);
+
+ // Check date header sanitization
+ headers = new StructuredHeaders();
+ headers.setHeader("Date", new Date("Fri, 6 Mar 2020 00:12:34 +0100"));
+ mimeText = "Date: Thu, 5 Mar 2020 23:12:00 +0000\r\n";
+ Assert.equal(headers.buildMimeText(true), mimeText);
+});
+
+/**
+ * Test that very long message id can be encoded without error.
+ */
+add_task(async function test_longMessageId() {
+ let msgId =
+ "<loqrvrxAUJXbUjUpqbrOJ8nHnJ49hmTREaUhehHZQv0AELQUM7ym6MUklPkt13aw4UD81bYIwO91pQL2OaeKMYVYD5hvZiRT2lSUmGtJkthgb3p5-y03p9bkxbnixgary7va1z0rv6hmd0yy69dm9exwga43h5k6266uwwchtjuxail7ipjhu6307yuft5bm186nu9vejf2joegwtq309cz9m-o3gwPZsvyB4qDpaAkxaj8iyh4OHc0kJsbQPQG8c5z6l3mmtwJuFHC4PxJnzAx9TyQzfnxhiXetQqFaNfvjNYetmNGMd4oq-sihw-d26z-bmdkvy47cloy2vwrnEYPKxtmjXtsmyFJGNxL7d1CeFIAOloSFAwccA6Onq6zPC9lfwWcAOFFje5XqkGVK2XNsUsFao5PR51WsOZStvoCzkqPuWB5PpJ791D9gzPXvGVa45ahuwgpmr1v8g1h5dalaytuxtpettthl506s7l4odqnkhufkvqkja56ulbd4ukgpbd88o3msjz3qk906pbfq6cahdecxoidplpbtsm-673718934717750999799265953521388769563044829819888815300763892678635939321303281062602679958225188.n050jeqcu1blxrm38i58q9dsws108c2m3xcc1tfmlgx8ya2wjyvzxyikgaaed3q6r@ZGCDPKIGJZGEPNVFFMXMTCMUFOPRMBFLIIPXSXECXKGNXBSDNPPHRBCXQRPCTUOCDDZVBEXYODLMFEQTUGBMHDJYUYus-575687677-2.673718934717750999799265953521388769563044829819888815300763892678635939321303281062602679958225188.invalid>";
+ let headers = new StructuredHeaders();
+ headers.setHeader("Message-ID", msgId);
+ Assert.equal(headers.getRawHeader("message-id"), msgId);
+});