summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/compose/test/unit/test_sendMailAddressIDN.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/compose/test/unit/test_sendMailAddressIDN.js')
-rw-r--r--comm/mailnews/compose/test/unit/test_sendMailAddressIDN.js231
1 files changed, 231 insertions, 0 deletions
diff --git a/comm/mailnews/compose/test/unit/test_sendMailAddressIDN.js b/comm/mailnews/compose/test/unit/test_sendMailAddressIDN.js
new file mode 100644
index 0000000000..56ab77c303
--- /dev/null
+++ b/comm/mailnews/compose/test/unit/test_sendMailAddressIDN.js
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/**
+ * Tests sending messages to addresses with non-ASCII characters.
+ */
+/* import-globals-from ../../../test/resources/alertTestUtils.js */
+load("../../../resources/alertTestUtils.js");
+
+var test = null;
+var server;
+var finished = false;
+
+var sentFolder;
+
+var kSender = "from@foo.invalid";
+var kToASCII = "to@foo.invalid";
+var kToValid = "to@v\u00E4lid.foo.invalid";
+var kToValidACE = "to@xn--vlid-loa.foo.invalid";
+var kToInvalid = "b\u00F8rken.to@invalid.foo.invalid";
+var kToInvalidWithoutDomain = "b\u00F8rken.to";
+var NS_ERROR_ILLEGAL_LOCALPART = 0x80553139;
+
+// for alertTestUtils.js
+let resolveAlert;
+function alertPS(parent, aDialogText, aText) {
+ var composeProps = Services.strings.createBundle(
+ "chrome://messenger/locale/messengercompose/composeMsgs.properties"
+ );
+ var expectedAlertMessage =
+ composeProps.GetStringFromName("sendFailed") +
+ "\n" +
+ composeProps
+ .GetStringFromName("errorIllegalLocalPart2")
+ // Without the domain, we currently don't display any name in the
+ // message part.
+ .replace("%s", test == kToInvalidWithoutDomain ? "" : test);
+
+ // we should only get here for the kToInvalid test case
+ Assert.equal(aText, expectedAlertMessage);
+ resolveAlert();
+}
+
+// message listener implementations
+function MsgSendListener(aRecipient, originalData) {
+ this.rcpt = aRecipient;
+ this.originalData = originalData;
+}
+
+/**
+ * @implements {nsIMsgSendListener}
+ * @implements {nsIMsgCopyServiceListener}
+ */
+MsgSendListener.prototype = {
+ // nsIMsgSendListener
+ onStartSending(aMsgID, aMsgSize) {},
+ onProgress(aMsgID, aProgress, aProgressMax) {},
+ onStatus(aMsgID, aMsg) {},
+ onStopSending(aMsgID, aStatus, aMsg, aReturnFile) {
+ try {
+ if (test == kToValid || test == kToASCII) {
+ Assert.equal(aStatus, 0);
+ do_check_transaction(server.playTransaction(), [
+ "EHLO test",
+ "MAIL FROM:<" +
+ kSender +
+ "> BODY=8BITMIME SIZE=" +
+ this.originalData.length,
+ "RCPT TO:<" + this.rcpt + ">",
+ "DATA",
+ ]);
+ // Compare data file to what the server received
+ Assert.equal(this.originalData, server._daemon.post);
+ } else {
+ Assert.equal(aStatus, NS_ERROR_ILLEGAL_LOCALPART);
+ do_check_transaction(server.playTransaction(), ["EHLO test"]);
+ // Local address (before the @) has non-ascii char(s) or the @ is
+ // missing from the address. An alert is triggered after the EHLO is
+ // sent. Nothing else occurs so we "finish" the test to avoid
+ // NS_ERROR_ABORT test failure due to timeout waiting for the send
+ // (which doesn't occurs) to complete.
+ }
+ } catch (e) {
+ do_throw(e);
+ } finally {
+ server.stop();
+ var thread = gThreadManager.currentThread;
+ while (thread.hasPendingEvents()) {
+ thread.processNextEvent(false);
+ }
+ do_test_finished();
+ }
+ },
+ onGetDraftFolderURI(aMsgID, aFolderURI) {},
+ onSendNotPerformed(aMsgID, aStatus) {},
+ onTransportSecurityError(msgID, status, secInfo, location) {},
+
+ // nsIMsgCopyServiceListener
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {},
+ GetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ Assert.equal(aStatus, 0);
+ try {
+ // Now do a comparison of what is in the sent mail folder
+ let msgData = mailTestUtils.loadMessageToString(
+ sentFolder,
+ mailTestUtils.firstMsgHdr(sentFolder)
+ );
+ // Skip the headers etc that mailnews adds
+ var pos = msgData.indexOf("From:");
+ Assert.notEqual(pos, -1);
+ msgData = msgData.substr(pos);
+ Assert.equal(this.originalData, msgData);
+ } catch (e) {
+ do_throw(e);
+ } finally {
+ finished = true;
+ }
+ },
+
+ // QueryInterface
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIMsgSendListener",
+ "nsIMsgCopyServiceListener",
+ ]),
+};
+
+async function doSendTest(aRecipient, aRecipientExpected, waitForPrompt) {
+ info(`Testing send to ${aRecipient} will get sent to ${aRecipientExpected}`);
+ let promiseAlertReceived = new Promise(resolve => {
+ resolveAlert = resolve;
+ });
+ test = aRecipient;
+ server = setupServerDaemon();
+ server.start();
+ var smtpServer = getBasicSmtpServer(server.port);
+ var identity = getSmtpIdentity(kSender, smtpServer);
+ Assert.equal(identity.doFcc, true);
+
+ // Random test file with data we don't actually care about. ;-)
+ var testFile = do_get_file("data/message1.eml");
+ var originalData = await IOUtils.readUTF8(testFile.path);
+
+ // Handle the server in a try/catch/finally loop so that we always will stop
+ // the server if something fails.
+ try {
+ do_test_pending();
+ var compFields = Cc[
+ "@mozilla.org/messengercompose/composefields;1"
+ ].createInstance(Ci.nsIMsgCompFields);
+ compFields.from = identity.email;
+ compFields.to = aRecipient;
+
+ var msgSend = Cc["@mozilla.org/messengercompose/send;1"].createInstance(
+ Ci.nsIMsgSend
+ );
+ msgSend.sendMessageFile(
+ identity,
+ "",
+ compFields,
+ testFile,
+ false,
+ false,
+ Ci.nsIMsgSend.nsMsgDeliverNow,
+ null,
+ new MsgSendListener(aRecipientExpected, originalData),
+ null,
+ null
+ );
+
+ server.performTest();
+ do_timeout(10000, function () {
+ if (!finished) {
+ do_throw("Notifications of message send/copy not received");
+ }
+ });
+ if (waitForPrompt) {
+ await promiseAlertReceived;
+ }
+ } catch (e) {
+ Assert.ok(false, "Send fail: " + e);
+ } finally {
+ server.stop();
+ var thread = gThreadManager.currentThread;
+ while (thread.hasPendingEvents()) {
+ thread.processNextEvent(true);
+ }
+ }
+}
+
+add_setup(function () {
+ registerAlertTestUtils();
+
+ // Ensure we have at least one mail account
+ localAccountUtils.loadLocalMailAccount();
+ MailServices.accounts.setSpecialFolders();
+ sentFolder = localAccountUtils.rootFolder.createLocalSubfolder("Sent");
+});
+
+add_task(async function plainASCIIRecipient() {
+ // Test 1:
+ // Plain ASCII recipient address.
+ await doSendTest(kToASCII, kToASCII, false);
+});
+
+add_task(async function domainContainsNonAscii() {
+ // Test 2:
+ // The recipient's domain part contains a non-ASCII character, hence the
+ // address needs to be converted to ACE before sending.
+ // The old code would just strip the non-ASCII character and try to send
+ // the message to the remaining - wrong! - address.
+ // The new code will translate the domain part to ACE for the SMTP
+ // transaction (only), i.e. the To: header will stay as stated by the sender.
+ await doSendTest(kToValid, kToValidACE, false);
+});
+
+add_task(async function localContainsNonAscii() {
+ // Test 3:
+ // The recipient's local part contains a non-ASCII character, which is not
+ // allowed with unextended SMTP.
+ // The old code would just strip the invalid character and try to send the
+ // message to the remaining - wrong! - address.
+ // The new code will present an informational message box and deny sending.
+ await doSendTest(kToInvalid, kToInvalid, true);
+});
+
+add_task(async function invalidCharNoAt() {
+ // Test 4:
+ // Bug 856506. invalid char without '@' causes crash.
+ await doSendTest(kToInvalidWithoutDomain, kToInvalidWithoutDomain, true);
+});