Revision control
Copy as Markdown
Other Tools
/* 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,
var { EwsServer } = ChromeUtils.importESModule(
);
var { localAccountUtils } = ChromeUtils.importESModule(
);
const EWS_SERVER_VERSION_PREF = "mail.ews.server_versions";
var ewsServer;
var incomingServer;
/**
* Instantiate an EWS client and use it to send a request to the mock EWS
* server.
*
* The request is a connectivity check, because it's a simple request with no
* parameters, but could be any operation, since we only care about the SOAP
* headers (and not the SOAP body).
*/
async function send_request_and_wait_for_response() {
await new Promise((resolve, reject) => {
// A mock listener that waits for a response to have been processed.
const listener = {
QueryInterface: ChromeUtils.generateQI(["nsIUrlListener"]),
OnStartRunningUrl() {},
OnStopRunningUrl(_url, exitCode) {
if (Components.isSuccessCode(exitCode)) {
resolve();
} else {
reject(exitCode);
}
},
};
// Build an EWS client and send the request.
const client = Cc["@mozilla.org/messenger/ews-client;1"].createInstance(
Ci.IEwsClient
);
client.initialize(incomingServer.getStringValue("ews_url"), incomingServer);
client.checkConnectivity(listener);
});
}
add_setup(() => {
// Create a new mock EWS server, and start it.
ewsServer = new EwsServer();
ewsServer.start();
// Create and configure the EWS incoming server.
incomingServer = localAccountUtils.create_incoming_server(
"ews",
ewsServer.port,
"user",
"password"
);
incomingServer.setStringValue(
"ews_url",
);
registerCleanupFunction(() => {
ewsServer.stop();
incomingServer.closeCachedConnections();
Services.prefs.clearUserPref(EWS_SERVER_VERSION_PREF);
});
});
/**
* Test that versions stored in prefs are correctly read, and result in the
* correct version being requested in EWS requests.
*/
add_task(async function test_send_with_version() {
// If no version is stored for the current server, we should default to
// Exchange2007_SP1.
await store_version_and_verify(null, "Exchange2007_SP1");
// All known identifiers should be read correctly.
await store_version_and_verify("Exchange2007", "Exchange2007");
await store_version_and_verify("Exchange2007_SP1", "Exchange2007_SP1");
await store_version_and_verify("Exchange2010", "Exchange2010");
await store_version_and_verify("Exchange2010_SP1", "Exchange2010_SP1");
await store_version_and_verify("Exchange2010_SP2", "Exchange2010_SP2");
await store_version_and_verify("Exchange2013", "Exchange2013");
await store_version_and_verify("Exchange2013_SP1", "Exchange2013_SP1");
// If an unknown version is stored for the current server, an error should be
// propagated to the consumer.
await Assert.rejects(
store_version_and_verify("UnknownFutureVersion", "UnknownFutureVersion"),
/NS_ERROR_UNEXPECTED/,
"unknown versions should cause an error to be propagated"
);
// If the pref does not contain valid JSON, we should default to
// Exchange2007_SP1.
Services.prefs.setCharPref(EWS_SERVER_VERSION_PREF, "{");
await send_request_and_wait_for_response();
Assert.equal(
ewsServer.lastRequestedVersion,
"Exchange2007_SP1",
"invalid JSON should result in using the default version"
);
// Reset the pref value to avoid side-effects in other tests.
Services.prefs.clearUserPref(EWS_SERVER_VERSION_PREF);
});
/**
* Store the given version identifier for the current server in the prefs, then
* send an EWS request and verify it requests the correct version.
*
* @param {?string} version - The version to store in prefs for the current
* server. `null` means we should replace the pref's value with an empty string.
* @param {string} expected - The version identifier we expect to find in
* request headers.
*/
async function store_version_and_verify(version, expected) {
if (version) {
Services.prefs.setCharPref(
EWS_SERVER_VERSION_PREF,
`{"${incomingServer.getStringValue("ews_url")}": "${version}"}`
);
} else {
Services.prefs.clearUserPref(EWS_SERVER_VERSION_PREF);
}
await send_request_and_wait_for_response();
// We don't use `Assert.stringMatches` here, because it performs the
// check using a regexp based on the expected value. Some version
// identifiers are substrings of others, and we don't want to
// accidentally match e.g. "Exchange2013_SP1" when we expect
// "Exchange2013".
Assert.equal(
ewsServer.lastRequestedVersion,
expected,
"stored version should match the expected identifier"
);
}
/**
* Test that versions are stored correctly in the dedicated pref.
*/
add_task(async function test_version_storage() {
// A lack of a version identifier in responses should not result in a version
// being stored.
await set_version_and_verify(null, null);
// All known versions identifiers should be stored. Since we don't clear the
// pref between calls to `set_version_and_verify`, this also ensures the
// stored version is updated accordingly when the server starts responding
// with a different identifier.
await set_version_and_verify("Exchange2007", "Exchange2007");
await set_version_and_verify("Exchange2007_SP1", "Exchange2007_SP1");
await set_version_and_verify("Exchange2010", "Exchange2010");
await set_version_and_verify("Exchange2010_SP1", "Exchange2010_SP1");
await set_version_and_verify("Exchange2010_SP2", "Exchange2010_SP2");
await set_version_and_verify("Exchange2013", "Exchange2013");
await set_version_and_verify("Exchange2013_SP1", "Exchange2013_SP1");
// A version identifier that is present in responses but isn't known should be
// stored as the most recent known version.
await set_version_and_verify("UnknownFutureVersion", "Exchange2013_SP1");
// A lack of a version identifier in a response, when we already know a
// version for the current server, should not result in the known version to
// be overwritten.
await set_version_and_verify("Exchange2010", "Exchange2010");
await set_version_and_verify(null, "Exchange2010");
// Reset the pref value to avoid side-effects in other tests.
Services.prefs.clearUserPref(EWS_SERVER_VERSION_PREF);
});
/**
* Sets the provided version on the mock EWS server, perform an EWS request, and
* verifies that the version that's been stored as a result matches the one we
* expect.
*
* @param {?string} version - The version identifier the mock EWS server should
* use in responses. `null` tells the server not to include a version identifier
* in responses.
* @param {?string} expected - The version identifier we expect to be stored
* after processing a response. `null` (or any falsy value) means we don't
* expect any version to be stored for the incoming server.
*
* @throws if the server responded with an error.
*/
async function set_version_and_verify(version, expected) {
// Set the version on the server.
ewsServer.version = version;
await send_request_and_wait_for_response();
// Compare the Exchange Server version stored for the server in prefs with the
// expected value.
const knownVersions = JSON.parse(
Services.prefs.getCharPref(EWS_SERVER_VERSION_PREF, "{}")
);
const storedVersion = knownVersions[incomingServer.getStringValue("ews_url")];
if (!expected) {
Assert.ok(!storedVersion, "should not have a version stored");
} else {
// We don't use `Assert.stringMatches` here, because it performs the
// check using a regexp based on the expected value. Some version
// identifiers are substrings of others, and we don't want to
// accidentally match e.g. "Exchange2013_SP1" when we expect
// "Exchange2013".
Assert.equal(
storedVersion,
expected,
"stored version should match the expected identifier"
);
}
}