diff options
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.js | 499 |
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(); + } +); |