Bug 1679730 - Part 3: Enable some unit tests for SmtpService.jsm. r=mkmelin

Differential Revision: https://phabricator.services.mozilla.com/D100068

--HG--
extra : amend_source : 15d9e8e4bf0e9e4a65506be52951b4f13575b8d7
This commit is contained in:
Ping Chen 2020-12-20 12:58:40 +02:00
Родитель 1326f357ac
Коммит 7ef1ff1956
10 изменённых файлов: 103 добавлений и 46 удалений

Просмотреть файл

@ -30,6 +30,7 @@ const EXPORTED_SYMBOLS = ["SmtpClient"];
var { setTimeout, clearTimeout } = ChromeUtils.import(
"resource://gre/modules/Timer.jsm"
);
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { SmtpAuthenticator } = ChromeUtils.import(
"resource:///modules/MailAuthenticator.jsm"
);
@ -78,6 +79,7 @@ class SmtpClient {
this.port = server.port || (this.options.useSecureTransport ? 465 : 25);
this.host = server.hostname;
this._server = server;
this._authenticator = new SmtpAuthenticator(server);
/**
@ -90,13 +92,15 @@ class SmtpClient {
? !!this.options.useSecureTransport
: this.port === 465;
this.options.name = this.options.name || "localhost"; // Hostname of the client, this will be used for introducing to the server
this.socket = false; // Downstream TCP socket to the SMTP server, created with mozTCPSocket
this.destroyed = false; // Indicates if the connection has been closed and can't be used anymore
this.waitDrain = false; // Keeps track if the downstream socket is currently full and a drain event should be waited for or not
// Private properties
// A list of capabilities detected from the EHLO response.
this._capabilities = [];
this._supportedAuth = []; // A list of authentication mechanisms detected from the EHLO response and which are compatible with this library
this._dataMode = false; // If true, accepts data from the upstream to be passed directly to the downstream socket. Used after the DATA command
this._lastDataBytes = ""; // Keep track of the last bytes to see how the terminating dot should be placed
@ -173,12 +177,12 @@ class SmtpClient {
* Initiates a new message by submitting envelope data, starting with
* `MAIL FROM:` command. Use after `onidle` event
*
* @param {Object} envelope Envelope object in the form of {from:"...", to:["..."]}
* @param {{from: string, to: string[], size: number}} envelope - The envelope object.
*/
useEnvelope(envelope) {
this._envelope = envelope || {};
this._envelope.from = [].concat(
this._envelope.from || "anonymous@" + this.options.name
this._envelope.from || "anonymous@" + this._getHelloArgument()
)[0];
this._envelope.to = [].concat(this._envelope.to || []);
@ -188,8 +192,21 @@ class SmtpClient {
this._envelope.responseQueue = [];
this._currentAction = this._actionMAIL;
let cmd = `MAIL FROM:<${this._envelope.from}>`;
if (
this._capabilities.includes("8BITMIME") &&
!Services.prefs.getBoolPref("mail.strictly_mime", false)
) {
cmd += " BODY=8BITMIME";
}
if (this._capabilities.includes("SMTPUTF8")) {
cmd += " SMTPUTF8";
}
if (this._capabilities.includes("SIZE")) {
cmd += ` SIZE=${this._envelope.size}`;
}
this.logger.debug("Sending MAIL FROM...");
this._sendCommand("MAIL FROM:<" + this._envelope.from + ">");
this._sendCommand(cmd);
}
/**
@ -323,15 +340,8 @@ class SmtpClient {
/**
* Connection listener that is run when the connection to the server is opened.
* Sets up different event handlers for the opened socket
*
* @event
* @param {Event} evt Event object. Not used
*/
_onOpen(event) {
if (event && event.data && event.data.proxyHostname) {
this.options.name = event.data.proxyHostname;
}
_onOpen() {
this.socket.ondata = this._onData.bind(this);
this.socket.onclose = this._onClose.bind(this);
@ -533,7 +543,7 @@ class SmtpClient {
* Intitiate authentication sequence if needed
*/
async _authenticateUser() {
if (this._supportedAuth.length == 0) {
if (!this.options.authMethod || this._supportedAuth.length == 0) {
// no need to authenticate, at least no data given
this._currentAction = this._actionIdle;
this.onidle(); // ready to take orders
@ -587,6 +597,21 @@ class SmtpClient {
this._onError(new Error("Unknown authentication method " + auth));
}
_getHelloArgument() {
let helloArgument = this._server.helloArgument;
if (helloArgument) {
return helloArgument;
}
let hostname = "localhost";
try {
hostname = Cc["@mozilla.org/network/dns-service"].getService(
Ci.nsIDNSService
).myHostName;
} catch (e) {}
return hostname;
}
// ACTIONS FOR RESPONSES FROM THE SMTP SERVER
/**
@ -601,15 +626,15 @@ class SmtpClient {
}
if (this.options.lmtp) {
this.logger.debug("Sending LHLO " + this.options.name);
this.logger.debug("Sending LHLO " + this._getHelloArgument());
this._currentAction = this._actionLHLO;
this._sendCommand("LHLO " + this.options.name);
this._sendCommand("LHLO " + this._getHelloArgument());
} else {
this.logger.debug("Sending EHLO " + this.options.name);
this.logger.debug("Sending EHLO " + this._getHelloArgument());
this._currentAction = this._actionEHLO;
this._sendCommand("EHLO " + this.options.name);
this._sendCommand("EHLO " + this._getHelloArgument());
}
}
@ -644,9 +669,11 @@ class SmtpClient {
}
// Try HELO instead
this.logger.warn("EHLO not successful, trying HELO " + this.options.name);
this.logger.warn(
"EHLO not successful, trying HELO " + this._getHelloArgument()
);
this._currentAction = this._actionHELO;
this._sendCommand("HELO " + this.options.name);
this._sendCommand("HELO " + this._getHelloArgument());
return;
}
@ -687,6 +714,12 @@ class SmtpClient {
}
}
for (let cap of ["8BITMIME", "SIZE", "SMTPUTF8"]) {
if (new RegExp(cap, "i").test(command.data)) {
this._capabilities.push(cap);
}
}
this._authenticateUser();
}
@ -708,7 +741,7 @@ class SmtpClient {
// restart protocol flow
this._currentAction = this._actionEHLO;
this._sendCommand("EHLO " + this.options.name);
this._sendCommand("EHLO " + this._getHelloArgument());
}
/**

Просмотреть файл

@ -253,7 +253,7 @@ SmtpServer.prototype = {
*/
_loadPrefs() {
this._prefs = Services.prefs.getBranch(`mail.smtpserver.${this._key}.`);
this._defaultPrefs = Services.prefs.getBranch("mail.smtpserver.default");
this._defaultPrefs = Services.prefs.getBranch("mail.smtpserver.default.");
},
/**

Просмотреть файл

@ -50,7 +50,7 @@ SmtpService.prototype = {
get servers() {
this._loadSmtpServers();
return this._servers.values();
return this._servers;
},
/**
@ -83,16 +83,22 @@ SmtpService.prototype = {
return;
}
fresh = false;
let from = MailServices.headerParser.makeFromDisplayAddress(
decodeURIComponent(recipients)
)[0].email;
let from = sender;
let to = MailServices.headerParser
.makeFromDisplayAddress(decodeURIComponent(recipients))
.map(rec => rec.email);
if (
!Services.prefs.getBoolPref("mail.smtp.useSenderForSmtpMailFrom", false)
) {
from = userIdentity.email;
}
client.useEnvelope({
from,
from: MailServices.headerParser.makeFromDisplayAddress(
decodeURIComponent(from)
)[0].email,
to,
size: messageFile.fileSize,
});
};
client.onready = () => {
@ -117,11 +123,11 @@ SmtpService.prototype = {
// let runningUrl = Services.io.newURI(server.serverURI);
let runningUrl = this._getRunningUri(server);
client.ondone = () => {
deliveryListener.OnStopRunningUrl(runningUrl, 0);
deliveryListener?.OnStopRunningUrl(runningUrl, 0);
client.close();
};
client.onerror = nsError => {
deliveryListener.OnStopRunningUrl(runningUrl, nsError);
deliveryListener?.OnStopRunningUrl(runningUrl, nsError);
};
},

Просмотреть файл

@ -5,5 +5,6 @@
XPCSHELL_TESTS_MANIFESTS += [
"unit/xpcshell-cpp.ini",
"unit/xpcshell-jsm-smtp.ini",
"unit/xpcshell-jsm.ini",
]

Просмотреть файл

@ -267,3 +267,4 @@ registerCleanupFunction(function() {
// Trigger the loading of nsMsgSend.cpp or MessageSend.jsm according to
// mailnews.send.jsmodule pref.
Cc["@mozilla.org/messengercompose/send-module-loader;1"].getService();
Cc["@mozilla.org/messengercompose/smtp-module-loader;1"].getService();

Просмотреть файл

@ -5,9 +5,11 @@ dupe-manifest =
support-files = data/*
prefs =
mailnews.send.jsmodule=false
mailnews.smtp.jsmodule=false
# No need to enable this for MessageSend.jsm because tmp file is not used for
# attachment.
[test_bug235432.js]
[include:xpcshell-shared.ini]
[include:xpcshell-smtp-failing.ini]

Просмотреть файл

@ -0,0 +1,10 @@
[DEFAULT]
head = head_compose.js
tail =
dupe-manifest =
support-files = data/*
prefs =
mailnews.send.jsmodule=true
mailnews.smtp.jsmodule=true
[include:xpcshell-shared.ini]

Просмотреть файл

@ -5,5 +5,6 @@ dupe-manifest =
support-files = data/*
prefs =
mailnews.send.jsmodule=true
mailnews.smtp.jsmodule=false
[include:xpcshell-shared.ini]
[include:xpcshell-smtp-failing.ini]

Просмотреть файл

@ -1,16 +1,11 @@
[test_autoReply.js]
skip-if = os == 'mac'
[test_attachment.js]
[test_attachment_intl.js]
[test_bug155172.js]
[test_bug474774.js]
[test_createRFC822Message.js]
[test_detectAttachmentCharset.js]
[test_expandMailingLists.js]
[test_fcc2.js]
[test_fccReply.js]
[test_longLines.js]
[test_mailTelemetry.js]
[test_mailtoURL.js]
[test_messageBody.js]
[test_messageHeaders.js]
@ -19,25 +14,13 @@ skip-if = os == 'mac'
[test_nsMsgCompose2.js]
[test_nsMsgCompose3.js]
[test_nsMsgCompose4.js]
[test_nsSmtpService1.js]
[test_saveDraft.js]
[test_sendBackground.js]
[test_sendMailAddressIDN.js]
[test_sendMailMessage.js]
[test_sendMessageFile.js]
[test_sendMessageLater.js]
[test_sendMessageLater2.js]
[test_sendMessageLater3.js]
[test_sendObserver.js]
[test_smtp8bitMime.js]
[test_smtpAuthMethods.js]
[test_smtpPassword.js]
[test_smtpPassword2.js]
[test_smtpPasswordFailure1.js]
[test_smtpPasswordFailure2.js]
[test_smtpPasswordFailure3.js]
[test_smtpProtocols.js]
[test_smtpProxy.js]
[test_smtpURL.js]
[test_splitRecipients.js]
[test_telemetry_compose.js]

Просмотреть файл

@ -0,0 +1,20 @@
# These are tests currently failing for SmtpServices.jsm, they will be moved
# back into xpcshell-shared.ini gradually.
[test_autoReply.js]
skip-if = os == 'mac'
[test_bug155172.js]
[test_bug474774.js]
[test_mailTelemetry.js]
[test_nsSmtpService1.js]
[test_sendBackground.js]
[test_sendMailAddressIDN.js]
[test_sendMessageLater.js]
[test_sendMessageLater2.js]
[test_sendMessageLater3.js]
[test_smtpAuthMethods.js]
[test_smtpPassword2.js]
[test_smtpPasswordFailure1.js]
[test_smtpPasswordFailure2.js]
[test_smtpPasswordFailure3.js]
[test_smtpProxy.js]