summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/extensions/test/xpcshell/test_ext_messages_attachments.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/extensions/test/xpcshell/test_ext_messages_attachments.js')
-rw-r--r--comm/mail/components/extensions/test/xpcshell/test_ext_messages_attachments.js499
1 files changed, 499 insertions, 0 deletions
diff --git a/comm/mail/components/extensions/test/xpcshell/test_ext_messages_attachments.js b/comm/mail/components/extensions/test/xpcshell/test_ext_messages_attachments.js
new file mode 100644
index 0000000000..e46e35afe7
--- /dev/null
+++ b/comm/mail/components/extensions/test/xpcshell/test_ext_messages_attachments.js
@@ -0,0 +1,499 @@
+/* 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/. */
+
+"use strict";
+
+var { ExtensionTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/ExtensionXPCShellUtils.sys.mjs"
+);
+var { TestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/TestUtils.sys.mjs"
+);
+
+add_task(
+ {
+ skip_if: () => IS_IMAP,
+ },
+ async function test_setup() {
+ let _account = createAccount();
+ let _testFolder = await createSubfolder(
+ _account.incomingServer.rootFolder,
+ "test1"
+ );
+
+ let textAttachment = {
+ body: "textAttachment",
+ filename: "test.txt",
+ contentType: "text/plain",
+ };
+ let binaryAttachment = {
+ body: btoa("binaryAttachment"),
+ filename: "test",
+ contentType: "application/octet-stream",
+ encoding: "base64",
+ };
+
+ await createMessages(_testFolder, {
+ count: 1,
+ subject: "0 attachments",
+ });
+ await createMessages(_testFolder, {
+ count: 1,
+ subject: "1 text attachment",
+ attachments: [textAttachment],
+ });
+ await createMessages(_testFolder, {
+ count: 1,
+ subject: "1 binary attachment",
+ attachments: [binaryAttachment],
+ });
+ await createMessages(_testFolder, {
+ count: 1,
+ subject: "2 attachments",
+ attachments: [binaryAttachment, textAttachment],
+ });
+ await createMessageFromFile(
+ _testFolder,
+ do_get_file("messages/nestedMessages.eml").path
+ );
+ }
+);
+
+add_task(
+ {
+ skip_if: () => IS_IMAP,
+ },
+ async function test_attachments() {
+ let extension = ExtensionTestUtils.loadExtension({
+ files: {
+ "background.js": async () => {
+ let [account] = await browser.accounts.list();
+ let testFolder = account.folders.find(f => f.name == "test1");
+ let { messages } = await browser.messages.list(testFolder);
+ browser.test.assertEq(5, messages.length);
+
+ let attachments, attachment, file;
+
+ // "0 attachments" message.
+
+ attachments = await browser.messages.listAttachments(messages[0].id);
+ browser.test.assertEq("0 attachments", messages[0].subject);
+ browser.test.assertEq(0, attachments.length);
+
+ // "1 text attachment" message.
+
+ attachments = await browser.messages.listAttachments(messages[1].id);
+ browser.test.assertEq("1 text attachment", messages[1].subject);
+ browser.test.assertEq(1, attachments.length);
+
+ attachment = attachments[0];
+ browser.test.assertEq("text/plain", attachment.contentType);
+ browser.test.assertEq("test.txt", attachment.name);
+ browser.test.assertEq("1.2", attachment.partName);
+ browser.test.assertEq(14, attachment.size);
+
+ file = await browser.messages.getAttachmentFile(
+ messages[1].id,
+ attachment.partName
+ );
+ // eslint-disable-next-line mozilla/use-isInstance
+ browser.test.assertTrue(file instanceof File);
+ browser.test.assertEq("test.txt", file.name);
+ browser.test.assertEq(14, file.size);
+
+ browser.test.assertEq("textAttachment", await file.text());
+
+ let reader = new FileReader();
+ let data = await new Promise(resolve => {
+ reader.onload = e => resolve(e.target.result);
+ reader.readAsDataURL(file);
+ });
+
+ browser.test.assertEq(
+ "data:text/plain;base64,dGV4dEF0dGFjaG1lbnQ=",
+ data
+ );
+
+ // "1 binary attachment" message.
+
+ attachments = await browser.messages.listAttachments(messages[2].id);
+ browser.test.assertEq("1 binary attachment", messages[2].subject);
+ browser.test.assertEq(1, attachments.length);
+
+ attachment = attachments[0];
+ browser.test.assertEq(
+ attachment.contentType,
+ "application/octet-stream"
+ );
+ browser.test.assertEq("test", attachment.name);
+ browser.test.assertEq("1.2", attachment.partName);
+ browser.test.assertEq(16, attachment.size);
+
+ file = await browser.messages.getAttachmentFile(
+ messages[2].id,
+ attachment.partName
+ );
+ // eslint-disable-next-line mozilla/use-isInstance
+ browser.test.assertTrue(file instanceof File);
+ browser.test.assertEq("test", file.name);
+ browser.test.assertEq(16, file.size);
+
+ browser.test.assertEq("binaryAttachment", await file.text());
+
+ reader = new FileReader();
+ data = await new Promise(resolve => {
+ reader.onload = e => resolve(e.target.result);
+ reader.readAsDataURL(file);
+ });
+
+ browser.test.assertEq(
+ "data:application/octet-stream;base64,YmluYXJ5QXR0YWNobWVudA==",
+ data
+ );
+
+ // "2 attachments" message.
+
+ attachments = await browser.messages.listAttachments(messages[3].id);
+ browser.test.assertEq("2 attachments", messages[3].subject);
+ browser.test.assertEq(2, attachments.length);
+
+ attachment = attachments[0];
+ browser.test.assertEq(
+ attachment.contentType,
+ "application/octet-stream"
+ );
+ browser.test.assertEq("test", attachment.name);
+ browser.test.assertEq("1.2", attachment.partName);
+ browser.test.assertEq(16, attachment.size);
+
+ file = await browser.messages.getAttachmentFile(
+ messages[3].id,
+ attachment.partName
+ );
+ // eslint-disable-next-line mozilla/use-isInstance
+ browser.test.assertTrue(file instanceof File);
+ browser.test.assertEq("test", file.name);
+ browser.test.assertEq(16, file.size);
+
+ browser.test.assertEq("binaryAttachment", await file.text());
+
+ attachment = attachments[1];
+ browser.test.assertEq("text/plain", attachment.contentType);
+ browser.test.assertEq("test.txt", attachment.name);
+ browser.test.assertEq("1.3", attachment.partName);
+ browser.test.assertEq(14, attachment.size);
+
+ file = await browser.messages.getAttachmentFile(
+ messages[3].id,
+ attachment.partName
+ );
+ // eslint-disable-next-line mozilla/use-isInstance
+ browser.test.assertTrue(file instanceof File);
+ browser.test.assertEq("test.txt", file.name);
+ browser.test.assertEq(14, file.size);
+
+ browser.test.assertEq("textAttachment", await file.text());
+
+ await browser.test.assertRejects(
+ browser.messages.listAttachments(0),
+ /^Message not found: \d+\.$/,
+ "Bad message ID should throw"
+ );
+ await browser.test.assertRejects(
+ browser.messages.getAttachmentFile(0, "1.2"),
+ /^Message not found: \d+\.$/,
+ "Bad message ID should throw"
+ );
+ browser.test.assertThrows(
+ () => browser.messages.getAttachmentFile(messages[3].id, "silly"),
+ /^Type error for parameter partName .* for messages\.getAttachmentFile\.$/,
+ "Bad part name should throw"
+ );
+ await browser.test.assertRejects(
+ browser.messages.getAttachmentFile(messages[3].id, "1.42"),
+ /Part 1.42 not found in message \d+\./,
+ "Non-existent part should throw"
+ );
+
+ browser.test.notifyPass("finished");
+ },
+ "utils.js": await getUtilsJS(),
+ },
+ manifest: {
+ background: { scripts: ["utils.js", "background.js"] },
+ permissions: ["accountsRead", "messagesRead"],
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("finished");
+ await extension.unload();
+ }
+);
+
+add_task(
+ {
+ skip_if: () => IS_IMAP,
+ },
+ async function test_messages_as_attachments() {
+ let extension = ExtensionTestUtils.loadExtension({
+ files: {
+ "background.js": async () => {
+ let [account] = await browser.accounts.list();
+ let testFolder = account.folders.find(f => f.name == "test1");
+ let { messages } = await browser.messages.list(testFolder);
+ browser.test.assertEq(5, messages.length);
+ let message = messages[4];
+
+ function validateMessage(msg, expectedValues) {
+ for (let expectedValueName in expectedValues) {
+ let value = msg[expectedValueName];
+ let expected = expectedValues[expectedValueName];
+ if (Array.isArray(expected)) {
+ browser.test.assertTrue(
+ Array.isArray(value),
+ `Value for ${expectedValueName} should be an Array.`
+ );
+ browser.test.assertEq(
+ expected.length,
+ value.length,
+ `Value for ${expectedValueName} should have the correct Array size.`
+ );
+ for (let i = 0; i < expected.length; i++) {
+ browser.test.assertEq(
+ expected[i],
+ value[i],
+ `Value for ${expectedValueName}[${i}] should be correct.`
+ );
+ }
+ } else if (expected instanceof Date) {
+ browser.test.assertTrue(
+ value instanceof Date,
+ `Value for ${expectedValueName} should be a Date.`
+ );
+ browser.test.assertEq(
+ expected.getTime(),
+ value.getTime(),
+ `Date value for ${expectedValueName} should be correct.`
+ );
+ } else {
+ browser.test.assertEq(
+ expected,
+ value,
+ `Value for ${expectedValueName} should be correct.`
+ );
+ }
+ }
+ }
+
+ // Request attachments.
+ let attachments = await browser.messages.listAttachments(message.id);
+ browser.test.assertEq(2, attachments.length);
+ browser.test.assertEq("1.2", attachments[0].partName);
+ browser.test.assertEq("1.3", attachments[1].partName);
+
+ browser.test.assertEq("message1.eml", attachments[0].name);
+ browser.test.assertEq("yellowPixel.png", attachments[1].name);
+
+ // Validate the returned MessageHeader for attached message1.eml.
+ let subMessage = attachments[0].message;
+ browser.test.assertTrue(
+ subMessage.id != message.id,
+ `Id of attached SubMessage (${subMessage.id}) should be different from the id of the outer message (${message.id})`
+ );
+ validateMessage(subMessage, {
+ date: new Date(958606367000),
+ author: "Superman <clark.kent@dailyplanet.com>",
+ recipients: ["Jimmy <jimmy.olsen@dailyplanet.com>"],
+ ccList: [],
+ bccList: [],
+ subject: "Test message 1",
+ new: false,
+ headersOnly: false,
+ flagged: false,
+ junk: false,
+ junkScore: 0,
+ headerMessageId: "sample-attached.eml@mime.sample",
+ size: 0,
+ tags: [],
+ external: true,
+ });
+
+ // Get attachments of sub-message messag1.eml.
+ let subAttachments = await browser.messages.listAttachments(
+ subMessage.id
+ );
+ browser.test.assertEq(4, subAttachments.length);
+ browser.test.assertEq("1.2.1.2", subAttachments[0].partName);
+ browser.test.assertEq("1.2.1.3", subAttachments[1].partName);
+ browser.test.assertEq("1.2.1.4", subAttachments[2].partName);
+ browser.test.assertEq("1.2.1.5", subAttachments[3].partName);
+
+ browser.test.assertEq("whitePixel.png", subAttachments[0].name);
+ browser.test.assertEq("greenPixel.png", subAttachments[1].name);
+ browser.test.assertEq("redPixel.png", subAttachments[2].name);
+ browser.test.assertEq("message2.eml", subAttachments[3].name);
+
+ // Validate the returned MessageHeader for sub-message message2.eml
+ // attached to sub-message message1.eml.
+ let subSubMessage = subAttachments[3].message;
+ browser.test.assertTrue(
+ ![message.id, subMessage.id].includes(subSubMessage.id),
+ `Id of attached SubSubMessage (${subSubMessage.id}) should be different from the id of the outer message (${message.id}) and from the SubMessage (${subMessage.id})`
+ );
+ validateMessage(subSubMessage, {
+ date: new Date(958519967000),
+ author: "Jimmy <jimmy.olsen@dailyplanet.com>",
+ recipients: ["Superman <clark.kent@dailyplanet.com>"],
+ ccList: [],
+ bccList: [],
+ subject: "Test message 2",
+ new: false,
+ headersOnly: false,
+ flagged: false,
+ junk: false,
+ junkScore: 0,
+ headerMessageId: "sample-nested-attached.eml@mime.sample",
+ size: 0,
+ tags: [],
+ external: true,
+ });
+
+ // Test getAttachmentFile().
+ // Note: This function has x-ray vision into sub-messages and can get
+ // any part inside the message, even if - technically - the attachments
+ // belong to subMessages. There is no difference between requesting
+ // part 1.2.1.2 from the main message or from message1.eml (part 1.2).
+ // X-ray vision from a sub-message back into a parent is not allowed.
+ let platform = await browser.runtime.getPlatformInfo();
+ let fileTests = [
+ {
+ partName: "1.2",
+ name: "message1.eml",
+ size:
+ platform.os != "win" &&
+ (account.type == "none" || account.type == "nntp")
+ ? 2517
+ : 2601,
+ text: "Message-ID: <sample-attached.eml@mime.sample>",
+ },
+ {
+ partName: "1.2.1.2",
+ name: "whitePixel.png",
+ size: 69,
+ data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC",
+ },
+ {
+ partName: "1.2.1.3",
+ name: "greenPixel.png",
+ size: 119,
+ data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAMSURBVBhXY+C76AoAAhUBJel4xsMAAAAASUVORK5CYII=",
+ },
+ {
+ partName: "1.2.1.4",
+ name: "redPixel.png",
+ size: 119,
+ data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAMSURBVBhXY+hgkAYAAbcApOp/9LEAAAAASUVORK5CYII=",
+ },
+ {
+ partName: "1.2.1.5",
+ name: "message2.eml",
+ size:
+ platform.os != "win" &&
+ (account.type == "none" || account.type == "nntp")
+ ? 838
+ : 867,
+ text: "Message-ID: <sample-nested-attached.eml@mime.sample>",
+ },
+ {
+ partName: "1.2.1.5.1.2",
+ name: "whitePixel.png",
+ size: 69,
+ data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC",
+ },
+ {
+ partName: "1.3",
+ name: "yellowPixel.png",
+ size: 119,
+ data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAMSURBVBhXY/j/iQEABOUB8pypNlQAAAAASUVORK5CYII=",
+ },
+ ];
+ let testMessages = [
+ {
+ id: message.id,
+ expectedFileCounts: 7,
+ },
+ {
+ id: subMessage.id,
+ subPart: "1.2.",
+ expectedFileCounts: 5,
+ },
+ {
+ id: subSubMessage.id,
+ subPart: "1.2.1.5.",
+ expectedFileCounts: 1,
+ },
+ ];
+ for (let msg of testMessages) {
+ let fileCounts = 0;
+ for (let test of fileTests) {
+ if (msg.subPart && !test.partName.startsWith(msg.subPart)) {
+ await browser.test.assertRejects(
+ browser.messages.getAttachmentFile(msg.id, test.partName),
+ `Part ${test.partName} not found in message ${msg.id}.`,
+ "Sub-message should not be able to get parts from parent message"
+ );
+ continue;
+ }
+ fileCounts++;
+
+ let file = await browser.messages.getAttachmentFile(
+ msg.id,
+ test.partName
+ );
+
+ // eslint-disable-next-line mozilla/use-isInstance
+ browser.test.assertTrue(file instanceof File);
+ browser.test.assertEq(test.name, file.name);
+ browser.test.assertEq(test.size, file.size);
+
+ if (test.text) {
+ browser.test.assertTrue(
+ (await file.text()).startsWith(test.text)
+ );
+ }
+
+ if (test.data) {
+ let reader = new FileReader();
+ let data = await new Promise(resolve => {
+ reader.onload = e => resolve(e.target.result);
+ reader.readAsDataURL(file);
+ });
+ browser.test.assertEq(
+ test.data,
+ data.replaceAll("\r\n", "\n").trim()
+ );
+ }
+ }
+ browser.test.assertEq(
+ msg.expectedFileCounts,
+ fileCounts,
+ "Should have requested to correct amount of attachment files."
+ );
+ }
+ browser.test.notifyPass("finished");
+ },
+ "utils.js": await getUtilsJS(),
+ },
+ manifest: {
+ background: { scripts: ["utils.js", "background.js"] },
+ permissions: ["accountsRead", "messagesRead"],
+ },
+ });
+
+ await extension.startup();
+ await extension.awaitFinish("finished");
+ await extension.unload();
+ }
+);