diff options
Diffstat (limited to 'comm/mailnews/compose/test/unit/head_compose.js')
-rw-r--r-- | comm/mailnews/compose/test/unit/head_compose.js | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/comm/mailnews/compose/test/unit/head_compose.js b/comm/mailnews/compose/test/unit/head_compose.js new file mode 100644 index 0000000000..6f874335e5 --- /dev/null +++ b/comm/mailnews/compose/test/unit/head_compose.js @@ -0,0 +1,280 @@ +var { MailServices } = ChromeUtils.import( + "resource:///modules/MailServices.jsm" +); +var { XPCOMUtils } = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +); +var { mailTestUtils } = ChromeUtils.import( + "resource://testing-common/mailnews/MailTestUtils.jsm" +); +var { localAccountUtils } = ChromeUtils.import( + "resource://testing-common/mailnews/LocalAccountUtils.jsm" +); + +var CC = Components.Constructor; + +// WebApps.jsm called by ProxyAutoConfig (PAC) requires a valid nsIXULAppInfo. +var { getAppInfo, newAppInfo, updateAppInfo } = ChromeUtils.importESModule( + "resource://testing-common/AppInfo.sys.mjs" +); +updateAppInfo(); + +// Ensure the profile directory is set up +do_get_profile(); + +var gDEPTH = "../../../../"; + +// Import the required setup scripts. + +/* import-globals-from ../../../test/resources/abSetup.js */ +load("../../../resources/abSetup.js"); + +// Import the smtp server scripts +var { + nsMailServer, + gThreadManager, + fsDebugNone, + fsDebugAll, + fsDebugRecv, + fsDebugRecvSend, +} = ChromeUtils.import("resource://testing-common/mailnews/Maild.jsm"); +var { SmtpDaemon, SMTP_RFC2821_handler } = ChromeUtils.import( + "resource://testing-common/mailnews/Smtpd.jsm" +); +var { AuthPLAIN, AuthLOGIN, AuthCRAM } = ChromeUtils.import( + "resource://testing-common/mailnews/Auth.jsm" +); + +var gDraftFolder; + +// Setup the daemon and server +function setupServerDaemon(handler) { + if (!handler) { + handler = function (d) { + return new SMTP_RFC2821_handler(d); + }; + } + var server = new nsMailServer(handler, new SmtpDaemon()); + return server; +} + +function getBasicSmtpServer(port = 1, hostname = "localhost") { + let server = localAccountUtils.create_outgoing_server( + port, + "user", + "password", + hostname + ); + + // Override the default greeting so we get something predicitable + // in the ELHO message + Services.prefs.setCharPref("mail.smtpserver.default.hello_argument", "test"); + + return server; +} + +function getSmtpIdentity(senderName, smtpServer) { + // Set up the identity + let identity = MailServices.accounts.createIdentity(); + identity.email = senderName; + identity.smtpServerKey = smtpServer.key; + + return identity; +} + +var test; + +function do_check_transaction(real, expected) { + if (Array.isArray(real)) { + real = real.at(-1); + } + // real.them may have an extra QUIT on the end, where the stream is only + // closed after we have a chance to process it and not them. We therefore + // excise this from the list + if (real.them[real.them.length - 1] == "QUIT") { + real.them.pop(); + } + + Assert.equal(real.them.join(","), expected.join(",")); + dump("Passed test " + test + "\n"); +} + +// This listener is designed just to call OnStopCopy() when its OnStopCopy +// function is called - the rest of the functions are unneeded for a lot of +// tests (but we can't use asyncCopyListener because we need the +// nsIMsgSendListener interface as well). +var copyListener = { + // nsIMsgSendListener + onStartSending(aMsgID, aMsgSize) {}, + onProgress(aMsgID, aProgress, aProgressMax) {}, + onStatus(aMsgID, aMsg) {}, + onStopSending(aMsgID, aStatus, aMsg, aReturnFile) {}, + onGetDraftFolderURI(aMsgID, aFolderURI) {}, + onSendNotPerformed(aMsgID, aStatus) {}, + onTransportSecurityError(msgID, status, secInfo, location) {}, + + // nsIMsgCopyServiceListener + OnStartCopy() {}, + OnProgress(aProgress, aProgressMax) {}, + SetMessageKey(aKey) {}, + GetMessageId(aMessageId) {}, + OnStopCopy(aStatus) { + /* globals OnStopCopy */ + OnStopCopy(aStatus); + }, + + // QueryInterface + QueryInterface: ChromeUtils.generateQI([ + "nsIMsgSendListener", + "nsIMsgCopyServiceListener", + ]), +}; + +var progressListener = { + onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) { + if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) { + this.resolve(gDraftFolder && mailTestUtils.firstMsgHdr(gDraftFolder)); + } + }, + + onProgressChange( + aWebProgress, + aRequest, + aCurSelfProgress, + aMaxSelfProgress, + aCurTotalProgress, + aMaxTotalProgress + ) {}, + onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {}, + onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {}, + onSecurityChange(aWebProgress, aRequest, state) {}, + onContentBlockingEvent(aWebProgress, aRequest, aEvent) {}, + + QueryInterface: ChromeUtils.generateQI([ + "nsIWebProgressListener", + "nsISupportsWeakReference", + ]), +}; + +function createMessage(aAttachment) { + let fields = Cc[ + "@mozilla.org/messengercompose/composefields;1" + ].createInstance(Ci.nsIMsgCompFields); + fields.from = "Nobody <nobody@tinderbox.test>"; + + let attachments = []; + if (aAttachment) { + let attachment = Cc[ + "@mozilla.org/messengercompose/attachment;1" + ].createInstance(Ci.nsIMsgAttachment); + if (aAttachment instanceof Ci.nsIFile) { + attachment.url = "file://" + aAttachment.path; + attachment.contentType = "text/plain"; + attachment.name = aAttachment.leafName; + } else { + attachment.url = "data:,sometext"; + attachment.name = aAttachment; + } + attachments = [attachment]; + } + return richCreateMessage(fields, attachments); +} + +function richCreateMessage( + fields, + attachments = [], + identity = null, + account = null +) { + let params = Cc[ + "@mozilla.org/messengercompose/composeparams;1" + ].createInstance(Ci.nsIMsgComposeParams); + params.composeFields = fields; + + let msgCompose = MailServices.compose.initCompose(params); + if (identity === null) { + identity = getSmtpIdentity(null, getBasicSmtpServer()); + } + + let rootFolder = localAccountUtils.rootFolder; + gDraftFolder = null; + // Make sure the drafts folder is empty + try { + gDraftFolder = rootFolder.getChildNamed("Drafts"); + } catch (e) { + // we don't have to remove the folder because it doesn't exist yet + gDraftFolder = rootFolder.createLocalSubfolder("Drafts"); + } + // Clear all messages + let msgs = [...gDraftFolder.msgDatabase.enumerateMessages()]; + if (msgs.length > 0) { + gDraftFolder.deleteMessages(msgs, null, true, false, null, false); + } + + // Set attachment + fields.removeAttachments(); + for (let attachment of attachments) { + fields.addAttachment(attachment); + } + + let progress = Cc["@mozilla.org/messenger/progress;1"].createInstance( + Ci.nsIMsgProgress + ); + let promise = new Promise((resolve, reject) => { + progressListener.resolve = resolve; + progressListener.reject = reject; + }); + progress.registerListener(progressListener); + msgCompose.sendMsg( + Ci.nsIMsgSend.nsMsgSaveAsDraft, + identity, + account ? account.key : "", + null, + progress + ); + return promise; +} + +function getAttachmentFromContent(aContent) { + function getBoundaryStringFromContent() { + let found = aContent.match( + /Content-Type: multipart\/mixed;\s+boundary="(.*?)"/ + ); + Assert.notEqual(found, null); + Assert.equal(found.length, 2); + + return found[1]; + } + + let boundary = getBoundaryStringFromContent(aContent); + let regex = new RegExp( + "\\r\\n\\r\\n--" + + boundary + + "\\r\\n" + + "([\\s\\S]*?)\\r\\n" + + "--" + + boundary + + "--", + "m" + ); + let attachments = aContent.match(regex); + Assert.notEqual(attachments, null); + Assert.equal(attachments.length, 2); + return attachments[1]; +} + +/** + * Get the body part of an MIME message. + * + * @param {string} content - The message content. + * @returns {string} + */ +function getMessageBody(content) { + let separatorIndex = content.indexOf("\r\n\r\n"); + Assert.equal(content.slice(-2), "\r\n", "Should end with a line break."); + return content.slice(separatorIndex + 4, -2); +} + +registerCleanupFunction(function () { + load(gDEPTH + "mailnews/resources/mailShutdown.js"); +}); |