diff options
Diffstat (limited to 'comm/mailnews/mime/test/unit/test_structured_headers.js')
-rw-r--r-- | comm/mailnews/mime/test/unit/test_structured_headers.js | 249 |
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); +}); |