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,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var { TestUtils } = ChromeUtils.importESModule(
);
var { MailServices } = ChromeUtils.importESModule(
);
var { localAccountUtils } = ChromeUtils.importESModule(
);
var { EwsServer } = ChromeUtils.importESModule(
);
var { RemoteFolder } = ChromeUtils.importESModule(
);
var incomingServer;
var ewsServer;
const ewsIdPropertyName = "ewsId";
add_setup(async function () {
// Ensure we have an on-disk profile.
do_get_profile();
// 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",
`http://127.0.0.1:${ewsServer.port}/EWS/Exchange.asmx`
);
registerCleanupFunction(() => {
ewsServer.stop();
incomingServer.closeCachedConnections();
});
});
/**
* Tests that triggering a folder hierarchy sync via
* `nsIMsgFolder::GetNewMessages` correctly populates subfolders.
*/
add_task(async function test_get_new_messages() {
// Populate the mock EWS server with all base folders.
const rootFolder = incomingServer.rootFolder;
await syncFolder(incomingServer, rootFolder);
// Check that all of the subfolders have been created.
for (const folder of ewsServer.folders) {
if (folder.distinguishedId == "msgfolderroot") {
// The root folder should not be a subfolder of itself.
continue;
}
const child = rootFolder.getChildNamed(folder.displayName);
Assert.ok(!!child, `${folder.displayName} should exist`);
}
// TODO: Check that items are also populated.
});
/**
* Tests that adding a new folder causes it to show up on the next sync via
* `nsIMSgFolder::GetNewMessages`. The implementation of the mock server also
* ensures that this test is testing repeat creations of existing folders as the
* mock server sends a complete sync for every request for new messages.
*/
add_task(async function test_create_folder() {
const newFolderName = "created_folder";
const rootFolder = incomingServer.rootFolder;
await syncFolder(incomingServer, rootFolder);
const childShouldNotExist = rootFolder.getChildNamed(newFolderName);
Assert.ok(!childShouldNotExist, `${newFolderName} should not exist.`);
ewsServer.appendRemoteFolder(
new RemoteFolder(newFolderName, "root", newFolderName, newFolderName)
);
await syncFolder(incomingServer, rootFolder);
const child = rootFolder.getChildNamed(newFolderName);
Assert.ok(!!child, `${newFolderName} should exist.`);
});
/**
* Tests that deleting a folder causes it to be remove on the next
* sync via `nsIMsgFolder::GetNewMessages`.
*/
add_task(async function test_delete_folder() {
const folderToDeleteName = "folder_to_delete";
ewsServer.appendRemoteFolder(
new RemoteFolder(
folderToDeleteName,
"root",
folderToDeleteName,
folderToDeleteName
)
);
const rootFolder = incomingServer.rootFolder;
await syncFolder(incomingServer, rootFolder);
const child = rootFolder.getChildNamed(folderToDeleteName);
Assert.ok(!!child, `${folderToDeleteName} should exist.`);
ewsServer.deleteRemoteFolderById(folderToDeleteName);
Assert.equal(1, ewsServer.deletedFolders.length);
await syncFolder(incomingServer, rootFolder);
const deletedChild = rootFolder.getChildNamed(folderToDeleteName);
Assert.ok(!deletedChild, `${folderToDeleteName} should not exist.`);
});
add_task(async function test_rename_folder() {
const initialFolderName = "rename_folder_original";
const finalFolderName = "rename_folder_new";
ewsServer.appendRemoteFolder(
new RemoteFolder(
initialFolderName,
"root",
initialFolderName,
initialFolderName
)
);
const rootFolder = incomingServer.rootFolder;
await syncFolder(incomingServer, rootFolder);
const child = rootFolder.getChildNamed(initialFolderName);
Assert.ok(!!child, `${initialFolderName} should exist.`);
const initialEwsId = child.getStringProperty(ewsIdPropertyName);
ewsServer.renameFolderById(initialFolderName, finalFolderName);
await syncFolder(incomingServer, rootFolder);
const renamedChild = rootFolder.getChildNamed(finalFolderName);
Assert.ok(!!renamedChild, `${finalFolderName} should exist.`);
const finalEwsId = renamedChild.getStringProperty(ewsIdPropertyName);
Assert.equal(
finalEwsId,
initialEwsId,
"EWS ID should be maintained through rename."
);
});
add_task(async function test_reparent_folder() {
const childName = "reparent_child";
const parent1Name = "reparent_parent_1";
const parent2Name = "reparent_parent_2";
const parentNames = [parent1Name, parent2Name];
parentNames.forEach(name => {
ewsServer.appendRemoteFolder(new RemoteFolder(name, "root", name, name));
});
const rootFolder = incomingServer.rootFolder;
await syncFolder(incomingServer, rootFolder);
const parent1 = rootFolder.getChildNamed(parent1Name);
Assert.ok(!!parent1, `${parent1Name} should exist.`);
const parent2 = rootFolder.getChildNamed(parent2Name);
Assert.ok(!!parent2, `${parent2Name} should exist.`);
// Add the child to the first parent.
ewsServer.appendRemoteFolder(
new RemoteFolder(childName, parent1Name, childName, childName)
);
await syncFolder(incomingServer, parent1);
const child = parent1.getChildNamed(childName);
Assert.ok(!!child, `${childName} should exist in ${parent1Name}`);
Assert.ok(
!parent2.getChildNamed(childName),
`${childName} should not exist in ${parent2Name}`
);
const initialEwsId = child.getStringProperty(ewsIdPropertyName);
ewsServer.reparentFolderById(childName, parent2Name);
await syncFolder(incomingServer, parent1);
await syncFolder(incomingServer, parent2);
const renamedChild = parent2.getChildNamed(childName);
Assert.ok(!!renamedChild, `${childName} should exist in ${parent2Name}`);
Assert.ok(
!parent1.getChildNamed(childName),
`${childName} should not exist in ${parent1Name}`
);
const finalEwsId = renamedChild.getStringProperty(ewsIdPropertyName);
Assert.equal(
finalEwsId,
initialEwsId,
"EWS ID should be maintained through reparent."
);
});
add_task(async function test_reparent_folder_tree() {
const parent1Name = "parent_1";
const parent2Name = "parent_2";
const child1Name = "child_1";
const child2Name = "child_2";
const child3Name = "child_3";
// Create the parents.
const parentNames = [parent1Name, parent2Name];
parentNames.forEach(name => {
ewsServer.appendRemoteFolder(new RemoteFolder(name, "root", name, name));
});
const rootFolder = incomingServer.rootFolder;
await syncFolder(incomingServer, rootFolder);
const parentFolders = parentNames.map(name => {
const parentFolder = rootFolder.getChildNamed(name);
Assert.ok(!!parentFolder, `${name} should exist in root folder.`);
return parentFolder;
});
// Create the hierarchy under the first parent:
// parent
// | -- child1
// | -- child2
// | -- child3
// Do this level-by-level to make it easier to know
// when the async operations have completed.
const ensureCreateFolder = async (childName, parentFolder) => {
ewsServer.appendRemoteFolder(
new RemoteFolder(childName, parentFolder.name, childName, childName)
);
await syncFolder(incomingServer, parentFolder);
const newChild = parentFolder.getChildNamed(childName);
Assert.ok(!!newChild, `${childName} should exist in ${parentFolder.name}`);
return newChild;
};
const child1Folder = await ensureCreateFolder(child1Name, parentFolders[0]);
const child2Folder = await ensureCreateFolder(child2Name, child1Folder);
const child3Folder = await ensureCreateFolder(child3Name, child2Folder);
const child1FolderEwsId = child1Folder.getStringProperty(ewsIdPropertyName);
const child2FolderEwsId = child2Folder.getStringProperty(ewsIdPropertyName);
const child3FolderEwsId = child3Folder.getStringProperty(ewsIdPropertyName);
const assertHierarchy = parentName => {
const parent = rootFolder.getChildNamed(parentName);
Assert.ok(!!parent, `${parentName} should exist in root folder.`);
const child1 = parent.getChildNamed(child1Name);
Assert.ok(!!child1, `${child1Name} should exist in ${parentName}`);
const child2 = child1.getChildNamed(child2Name);
Assert.ok(!!child2, `${child2Name} should exist in ${child1Name}`);
const child3 = child2.getChildNamed(child3Name);
Assert.ok(!!child3, `${child3Name} should exist in ${child2Name}`);
};
assertHierarchy(parent1Name);
// Reparent the entire hierarchy at once and wait for
// the full operation to complete.
ewsServer.reparentFolderById(child1Name, parent2Name);
await syncFolder(incomingServer, parentFolders[0]);
await syncFolder(incomingServer, parentFolders[1]);
assertHierarchy(parent2Name);
const child1Reparented = parentFolders[1].getChildNamed(child1Name);
const child2Reparented = child1Reparented.getChildNamed(child2Name);
const child3Reparented = child2Reparented.getChildNamed(child3Name);
Assert.equal(
child1Reparented.getStringProperty(ewsIdPropertyName),
child1FolderEwsId,
`${child1Name} EWS ID should be the same after reparenting.`
);
Assert.equal(
child2Reparented.getStringProperty(ewsIdPropertyName),
child2FolderEwsId,
`${child2Name} EWS ID should be the same after reparenting.`
);
Assert.equal(
child3Reparented.getStringProperty(ewsIdPropertyName),
child3FolderEwsId,
`${child3Name} EWS ID should be the same after reparenting.`
);
});