summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/shared-modules/CloudfileHelpers.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/shared-modules/CloudfileHelpers.jsm')
-rw-r--r--comm/mail/test/browser/shared-modules/CloudfileHelpers.jsm278
1 files changed, 278 insertions, 0 deletions
diff --git a/comm/mail/test/browser/shared-modules/CloudfileHelpers.jsm b/comm/mail/test/browser/shared-modules/CloudfileHelpers.jsm
new file mode 100644
index 0000000000..a8c937e770
--- /dev/null
+++ b/comm/mail/test/browser/shared-modules/CloudfileHelpers.jsm
@@ -0,0 +1,278 @@
+/* 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/. */
+
+"use strict";
+
+const EXPORTED_SYMBOLS = [
+ "gMockCloudfileManager",
+ "MockCloudfileAccount",
+ "getFile",
+ "collectFiles",
+ "CloudFileTestProvider",
+];
+
+var fdh = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+
+var { Assert } = ChromeUtils.importESModule(
+ "resource://testing-common/Assert.sys.mjs"
+);
+var { cloudFileAccounts } = ChromeUtils.import(
+ "resource:///modules/cloudFileAccounts.jsm"
+);
+
+var kDefaults = {
+ type: "default",
+ displayName: "default",
+ iconURL: "chrome://messenger/content/extension.svg",
+ accountKey: null,
+ managementURL: "",
+ reuseUploads: true,
+ authErr: cloudFileAccounts.constants.authErr,
+ offlineErr: cloudFileAccounts.constants.offlineErr,
+ uploadErr: cloudFileAccounts.constants.uploadErr,
+ uploadWouldExceedQuota: cloudFileAccounts.constants.uploadWouldExceedQuota,
+ uploadExceedsFileLimit: cloudFileAccounts.constants.uploadExceedsFileLimit,
+ uploadCancelled: cloudFileAccounts.constants.uploadCancelled,
+};
+
+function getFile(aFilename, aRoot) {
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ file.initWithPath(aRoot);
+ file.append(aFilename);
+ Assert.ok(file.exists, "File " + aFilename + " does not exist.");
+ return file;
+}
+
+/**
+ * Helper function for getting the nsIFile's for some files located
+ * in a subdirectory of the test directory.
+ *
+ * @param aFiles an array of filename strings for files underneath the test
+ * file directory.
+ * @param aFileRoot the file who's parent directory we should start looking
+ * for aFiles in.
+ *
+ * Example:
+ * let files = collectFiles(['./data/testFile1', './data/testFile2'],
+ * __file__);
+ */
+function collectFiles(aFiles, aFileRoot) {
+ return aFiles.map(filename => getFile(filename, aFileRoot));
+}
+
+function MockCloudfileAccount() {
+ for (let someDefault in kDefaults) {
+ this[someDefault] = kDefaults[someDefault];
+ }
+}
+
+MockCloudfileAccount.prototype = {
+ _nextId: 1,
+ _uploads: new Map(),
+
+ init(aAccountKey, aOverrides = {}) {
+ for (let override in aOverrides) {
+ this[override] = aOverrides[override];
+ }
+ this.accountKey = aAccountKey;
+
+ Services.prefs.setCharPref(
+ "mail.cloud_files.accounts." + aAccountKey + ".displayName",
+ aAccountKey
+ );
+ Services.prefs.setCharPref(
+ "mail.cloud_files.accounts." + aAccountKey + ".type",
+ aAccountKey
+ );
+ cloudFileAccounts._accounts.set(aAccountKey, this);
+ },
+
+ renameFile(window, uploadId, newName) {
+ if (this.renameError) {
+ throw Components.Exception(
+ this.renameError.message,
+ this.renameError.result
+ );
+ }
+
+ let upload = this._uploads.get(uploadId);
+ upload.url = `https://www.example.com/${this.accountKey}/${newName}`;
+ upload.name = newName;
+ return upload;
+ },
+
+ isReusedUpload() {
+ return false;
+ },
+
+ uploadFile(window, aFile) {
+ if (this.uploadError) {
+ return Promise.reject(
+ Components.Exception(this.uploadError.message, this.uploadError.result)
+ );
+ }
+
+ return new Promise((resolve, reject) => {
+ let upload = {
+ // Values used in the WebExtension CloudFile type.
+ id: this._nextId++,
+ url: this.urlForFile(aFile),
+ name: aFile.leafName,
+ // Properties of the local file.
+ path: aFile.path,
+ size: aFile.exists() ? aFile.fileSize : 0,
+ // Use aOverrides to set these.
+ serviceIcon: this.serviceIcon || this.iconURL,
+ serviceName: this.serviceName || this.displayName,
+ serviceUrl: this.serviceUrl || "",
+ downloadPasswordProtected: this.downloadPasswordProtected || false,
+ downloadLimit: this.downloadLimit || 0,
+ downloadExpiryDate: this.downloadExpiryDate || null,
+ // Usage tracking.
+ immutable: false,
+ };
+ this._uploads.set(upload.id, upload);
+ gMockCloudfileManager.inProgressUploads.add({
+ resolve,
+ reject,
+ resolveData: upload,
+ });
+ });
+ },
+
+ urlForFile(aFile) {
+ return `https://www.example.com/${this.accountKey}/${aFile.leafName}`;
+ },
+
+ cancelFileUpload(window, aUploadId) {
+ throw Components.Exception("", Cr.NS_ERROR_NOT_IMPLEMENTED);
+ },
+
+ deleteFile(window, aUploadId) {
+ return new Promise(resolve => fdh.mc.window.setTimeout(resolve));
+ },
+};
+
+var gMockCloudfileManager = {
+ _mock_map: {},
+
+ register(aID, aOverrides) {
+ if (!aID) {
+ aID = "default";
+ }
+
+ if (!aOverrides) {
+ aOverrides = {};
+ }
+
+ cloudFileAccounts.registerProvider(aID, {
+ type: aID,
+ displayName: aID,
+ iconURL: "chrome://messenger/content/extension.svg",
+ initAccount(accountKey, aAccountOverrides = {}) {
+ let account = new MockCloudfileAccount();
+ for (let override in aOverrides) {
+ if (!aAccountOverrides.hasOwnProperty(override)) {
+ aAccountOverrides[override] = aOverrides[override];
+ }
+ }
+ account.init(accountKey, aAccountOverrides);
+ return account;
+ },
+ });
+ },
+
+ unregister(aID) {
+ if (!aID) {
+ aID = "default";
+ }
+
+ cloudFileAccounts.unregisterProvider(aID);
+ },
+
+ inProgressUploads: new Set(),
+ resolveUploads() {
+ let uploads = [];
+ for (let upload of this.inProgressUploads.values()) {
+ uploads.push(upload.resolveData);
+ upload.resolve(upload.resolveData);
+ }
+ this.inProgressUploads.clear();
+ return uploads;
+ },
+ rejectUploads() {
+ for (let upload of this.inProgressUploads.values()) {
+ upload.reject(
+ Components.Exception(
+ "Upload error.",
+ cloudFileAccounts.constants.uploadErr
+ )
+ );
+ }
+ this.inProgressUploads.clear();
+ },
+};
+
+class CloudFileTestProvider {
+ constructor(name = "CloudFileTestProvider") {
+ this.extension = null;
+ this.name = name;
+ }
+
+ get providerType() {
+ return `ext-${this.extension.id}`;
+ }
+
+ /**
+ * Register an extension based cloudFile provider.
+ *
+ * @param testScope - scope of the test, mostly "this"
+ * @param [background] - optional background script, overriding the default
+ */
+ async register(testScope, background) {
+ if (!testScope) {
+ throw new Error("Missing testScope for CloudFileTestProvider.init().");
+ }
+
+ async function default_background() {
+ function fileListener(account, { id, name, data }, tab, relatedFileInfo) {
+ return { url: "https://example.com/" + name };
+ }
+ browser.cloudFile.onFileUpload.addListener(fileListener);
+ }
+
+ this.extension = testScope.ExtensionTestUtils.loadExtension({
+ files: {
+ "background.js": background || default_background,
+ },
+ manifest: {
+ cloud_file: {
+ name: this.name,
+ management_url: "/content/management.html",
+ },
+ applications: { gecko: { id: `${this.name}@mochi.test` } },
+ background: { scripts: ["background.js"] },
+ },
+ });
+
+ await this.extension.startup();
+ }
+
+ async unregister() {
+ cloudFileAccounts.unregisterProvider(this.providerType);
+ await this.extension.unload();
+ }
+
+ async createAccount(displayName) {
+ let account = await cloudFileAccounts.createAccount(this.providerType);
+ cloudFileAccounts.setDisplayName(account, displayName);
+ return account;
+ }
+
+ removeAccount(aKeyOrAccount) {
+ return cloudFileAccounts.removeAccount(aKeyOrAccount);
+ }
+}