/* 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/. */ var { MailServices } = ChromeUtils.importESModule( "resource:///modules/MailServices.sys.mjs" ); const { PromiseTestUtils } = ChromeUtils.importESModule( "resource://testing-common/mailnews/PromiseTestUtils.sys.mjs" ); var account; var server; var identity; var smtpServer; var msgSendLater = Cc["@mozilla.org/messengercompose/sendlater;1"].getService( Ci.nsIMsgSendLater ); add_setup(() => { // Ensure we have a local mail account, an normal account and appropriate // servers and identities. account = MailServices.accounts.createAccount(); const incomingServer = MailServices.accounts.createIncomingServer( "test", "localhost", "pop3" ); smtpServer = getBasicSmtpServer(1); identity = getSmtpIdentity("identity@foo.invalid", smtpServer); account.addIdentity(identity); account.defaultIdentity = identity; account.incomingServer = incomingServer; MailServices.accounts.defaultAccount = account; Assert.equal(identity.doFcc, true); localAccountUtils.loadLocalMailAccount(); localAccountUtils.rootFolder.createLocalSubfolder("Sent"); MailServices.accounts.setSpecialFolders(); // Check that the send later service thinks we don't have messages to send Assert.equal(msgSendLater.hasUnsentMessages(identity), false); registerCleanupFunction(() => { server.stop(); MailServices.accounts.removeAccount(account, false); var thread = Services.tm.currentThread; while (thread.hasPendingEvents()) { thread.processNextEvent(true); } }); }); async function test_dsn_message_id(filename, messageIdPattern) { // Now prepare to actually "send" the message later, i.e. dump it in the // unsent messages folder. var compFields = Cc[ "@mozilla.org/messengercompose/composefields;1" ].createInstance(Ci.nsIMsgCompFields); // Sender and recipient are required for sendMessageFile but SMTP transaction values will // be used directly from mail body. We don't set the DSN flag here, because // this is handled by the X-Mozilla-Draft-Info header in the message content. compFields.from = "irrelevant@foo.invalid"; compFields.to = "irrelevant@foo.invalid"; const copyListener = new PromiseTestUtils.PromiseCopyListener(); // Method from nsIMsgSendListener that's expected on the listener. copyListener.onGetDraftFolderURI = () => {}; // Queue the message for sending. var msgSend = Cc["@mozilla.org/messengercompose/send;1"].createInstance( Ci.nsIMsgSend ); msgSend.sendMessageFile( identity, account.key, compFields, do_get_file(filename), false, false, Ci.nsIMsgSend.nsMsgQueueForLater, null, copyListener, null, null ); await copyListener.promise; // Set up the SMTP server. server = setupServerDaemon(); // Start the fake SMTP server server.start(); smtpServer.QueryInterface(Ci.nsISmtpServer).port = server.port; var sendListener = new PromiseTestUtils.PromiseSendLaterListener(); msgSendLater.addListener(sendListener); // Send the unsent message. msgSendLater.sendUnsentMessages(identity); server.performTest(); const sendResult = await sendListener.promise; // Test that the message has been sent without any issue. We don't need to // look at the nsresult passed to onStopSending, because the promise would // have been rejected if it wasn't NS_OK. Assert.equal( sendResult.totalTried, 1, "1 message send should have been attempted" ); Assert.equal( sendResult.successful, 1, "the message should have been sent successfully" ); Assert.equal( msgSendLater.sendingMessages, false, "the nsIMsgSendLater instance should have stopped sending messages" ); // Test that we sent a message ID that matches with the expected pattern. const mailFromLine = server.playTransaction().them[1]; const testRegExp = new RegExp(`RET=FULL ENVID=<${messageIdPattern}>`); Assert.ok( testRegExp.test(mailFromLine), "smtp client should send a valid message ID" ); } /** * Tests that a delayed send of a message with DSN turned on over SMTP results * in an SMTP command that includes a valid message ID, even if the message does * not include a Message-ID header. */ add_task(async function test_dsn_message_id_without_header() { await test_dsn_message_id("data/sendlater_dsn.eml", "[a-z0-9-]+@foo.invalid"); }); /** * Tests that a delayed send of a message with DSN turned on over SMTP results * in an SMTP command that includes the message ID from the message's Message-ID * header. */ add_task(async function test_dsn_message_id_with_header() { await test_dsn_message_id( "data/sendlater_dsn_with_message_id.eml", "f30c39e6-b14b-405a-8bf7-2ccc81fd1f6f@foo.invalid" ); });