mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1901308 - Show profile backup errors and keep modals open r=backup-reviewers,fluent-reviewers,firefox-desktop-core-reviewers ,mconley,bolsson
Currently, clicking "confirm" buttons on modals in the profile backup settings menu will always close the modals regardless of whether the operation succeeded or failed. In the case of errors, users don't know that something went wrong. It's better to keep the modals open and display an error so that the user knows what to do next and can try to fix the issue, if applicable. Differential Revision: https://phabricator.services.mozilla.com/D218358
This commit is contained in:
parent
ab8fa1ab81
commit
6c1381ca4b
@ -456,12 +456,14 @@ let JSWINDOWACTORS = {
|
||||
esModuleURI: "resource:///actors/BackupUIChild.sys.mjs",
|
||||
events: {
|
||||
"BackupUI:InitWidget": { wantUntrusted: true },
|
||||
"BackupUI:ToggleScheduledBackups": { wantUntrusted: true },
|
||||
"BackupUI:EnableScheduledBackups": { wantUntrusted: true },
|
||||
"BackupUI:DisableScheduledBackups": { wantUntrusted: true },
|
||||
"BackupUI:ShowFilepicker": { wantUntrusted: true },
|
||||
"BackupUI:GetBackupFileInfo": { wantUntrusted: true },
|
||||
"BackupUI:RestoreFromBackupFile": { wantUntrusted: true },
|
||||
"BackupUI:RestoreFromBackupChooseFile": { wantUntrusted: true },
|
||||
"BackupUI:ToggleEncryption": { wantUntrusted: true },
|
||||
"BackupUI:EnableEncryption": { wantUntrusted: true },
|
||||
"BackupUI:DisableEncryption": { wantUntrusted: true },
|
||||
"BackupUI:RerunEncryption": { wantUntrusted: true },
|
||||
"BackupUI:ShowBackupLocation": { wantUntrusted: true },
|
||||
"BackupUI:EditBackupLocation": { wantUntrusted: true },
|
||||
|
@ -2753,6 +2753,7 @@ export class BackupService extends EventTarget {
|
||||
lazy.logConsole.error(
|
||||
`Failed to set parent directory ${parentDirPath}. ${e}`
|
||||
);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,26 @@ export class BackupUIChild extends JSWindowActorChild {
|
||||
if (event.type == "BackupUI:InitWidget") {
|
||||
this.#inittedWidgets.add(event.target);
|
||||
this.sendAsyncMessage("RequestState");
|
||||
} else if (event.type == "BackupUI:ToggleScheduledBackups") {
|
||||
this.sendAsyncMessage("ToggleScheduledBackups", event.detail);
|
||||
} else if (event.type == "BackupUI:EnableScheduledBackups") {
|
||||
const target = event.target;
|
||||
|
||||
const result = await this.sendQuery(
|
||||
"EnableScheduledBackups",
|
||||
event.detail
|
||||
);
|
||||
if (result.success) {
|
||||
target.close();
|
||||
} else {
|
||||
target.enableBackupErrorCode = result.errorCode;
|
||||
}
|
||||
} else if (event.type == "BackupUI:DisableScheduledBackups") {
|
||||
const target = event.target;
|
||||
|
||||
this.sendAsyncMessage("DisableScheduledBackups", event.detail);
|
||||
// backups will always end up disabled even if there was an error
|
||||
// with other bookkeeping related to turning off backups
|
||||
|
||||
target.close();
|
||||
} else if (event.type == "BackupUI:ShowFilepicker") {
|
||||
let targetNodeName = event.target.nodeName;
|
||||
let { path, filename, iconURL } = await this.sendQuery("ShowFilepicker", {
|
||||
@ -79,10 +97,33 @@ export class BackupUIChild extends JSWindowActorChild {
|
||||
}
|
||||
} else if (event.type == "BackupUI:RestoreFromBackupChooseFile") {
|
||||
this.sendAsyncMessage("RestoreFromBackupChooseFile");
|
||||
} else if (event.type == "BackupUI:ToggleEncryption") {
|
||||
this.sendAsyncMessage("ToggleEncryption", event.detail);
|
||||
} else if (event.type == "BackupUI:EnableEncryption") {
|
||||
const target = event.target;
|
||||
|
||||
const result = await this.sendQuery("EnableEncryption", event.detail);
|
||||
if (result.success) {
|
||||
target.close();
|
||||
} else {
|
||||
target.enableEncryptionErrorCode = result.errorCode;
|
||||
}
|
||||
} else if (event.type == "BackupUI:DisableEncryption") {
|
||||
const target = event.target;
|
||||
|
||||
const result = await this.sendQuery("DisableEncryption", event.detail);
|
||||
if (result.success) {
|
||||
target.close();
|
||||
} else {
|
||||
target.disableEncryptionErrorCode = result.errorCode;
|
||||
}
|
||||
} else if (event.type == "BackupUI:RerunEncryption") {
|
||||
this.sendAsyncMessage("RerunEncryption", event.detail);
|
||||
const target = event.target;
|
||||
|
||||
const result = await this.sendQuery("RerunEncryption", event.detail);
|
||||
if (result.success) {
|
||||
target.close();
|
||||
} else {
|
||||
target.rerunEncryptionErrorCode = result.errorCode;
|
||||
}
|
||||
} else if (event.type == "BackupUI:ShowBackupLocation") {
|
||||
this.sendAsyncMessage("ShowBackupLocation");
|
||||
} else if (event.type == "BackupUI:EditBackupLocation") {
|
||||
|
@ -82,50 +82,37 @@ export class BackupUIParent extends JSWindowActorParent {
|
||||
async receiveMessage(message) {
|
||||
if (message.name == "RequestState") {
|
||||
this.sendState();
|
||||
} else if (message.name == "ToggleScheduledBackups") {
|
||||
let { isScheduledBackupsEnabled, parentDirPath, password } = message.data;
|
||||
|
||||
if (isScheduledBackupsEnabled) {
|
||||
} else if (message.name == "EnableScheduledBackups") {
|
||||
try {
|
||||
let { parentDirPath, password } = message.data;
|
||||
if (parentDirPath) {
|
||||
this.#bs.setParentDirPath(parentDirPath);
|
||||
/**
|
||||
* TODO: display an error and do not attempt to toggle scheduled backups if there
|
||||
* is a problem with setting the parent directory (bug 1901308).
|
||||
*/
|
||||
}
|
||||
|
||||
if (password) {
|
||||
try {
|
||||
await this.#bs.enableEncryption(password);
|
||||
} catch (e) {
|
||||
/**
|
||||
* TODO: display en error and do not attempt to toggle scheduled backups if there is a
|
||||
* problem with enabling encryption (bug 1901308)
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (this.#bs.state.encryptionEnabled) {
|
||||
await this.#bs.disableEncryption();
|
||||
}
|
||||
await this.#bs.deleteLastBackup();
|
||||
} catch (e) {
|
||||
// no-op so that scheduled backups can still be turned off
|
||||
await this.#bs.enableEncryption(password);
|
||||
}
|
||||
this.#bs.setScheduledBackups(true);
|
||||
} catch (e) {
|
||||
lazy.logConsole.error(`Failed to enable scheduled backups`, e);
|
||||
return { success: false, errorCode: e.cause || lazy.ERRORS.UNKNOWN };
|
||||
}
|
||||
|
||||
this.#bs.setScheduledBackups(isScheduledBackupsEnabled);
|
||||
|
||||
return true;
|
||||
|
||||
/**
|
||||
* TODO: (Bug 1900125) we should create a backup at the specified dir path once we turn on
|
||||
* scheduled backups. The backup folder in the chosen directory should contain
|
||||
* the archive file, which we create using BackupService.createArchive implemented in
|
||||
* Bug 1897498.
|
||||
*/
|
||||
return { success: true };
|
||||
} else if (message.name == "DisableScheduledBackups") {
|
||||
try {
|
||||
if (this.#bs.state.encryptionEnabled) {
|
||||
await this.#bs.disableEncryption();
|
||||
}
|
||||
await this.#bs.deleteLastBackup();
|
||||
} catch (e) {
|
||||
// no-op so that scheduled backups can still be turned off
|
||||
}
|
||||
this.#bs.setScheduledBackups(false);
|
||||
} else if (message.name == "ShowFilepicker") {
|
||||
let { win, filter, displayDirectoryPath } = message.data;
|
||||
|
||||
@ -191,52 +178,45 @@ export class BackupUIParent extends JSWindowActorParent {
|
||||
return { success: false, errorCode: e.cause || lazy.ERRORS.UNKNOWN };
|
||||
}
|
||||
return { success: true };
|
||||
} else if (message.name == "ToggleEncryption") {
|
||||
let { isEncryptionEnabled, password } = message.data;
|
||||
|
||||
if (!isEncryptionEnabled) {
|
||||
try {
|
||||
await this.#bs.disableEncryption();
|
||||
/**
|
||||
* TODO: (Bug 1901640) after disabling encryption, recreate the backup,
|
||||
* this time without sensitive data.
|
||||
*/
|
||||
} catch (e) {
|
||||
/**
|
||||
* TODO: (Bug 1901308) maybe display an error if there is a problem with
|
||||
* disabling encryption.
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
await this.#bs.enableEncryption(password);
|
||||
/**
|
||||
* TODO: (Bug 1901640) after enabling encryption, recreate the backup,
|
||||
* this time with sensitive data.
|
||||
*/
|
||||
} catch (e) {
|
||||
/**
|
||||
* TODO: (Bug 1901308) maybe display an error if there is a problem with
|
||||
* enabling encryption.
|
||||
*/
|
||||
}
|
||||
} else if (message.name == "EnableEncryption") {
|
||||
try {
|
||||
await this.#bs.enableEncryption(message.data.password);
|
||||
} catch (e) {
|
||||
lazy.logConsole.error(`Failed to enable encryption`, e);
|
||||
return { success: false, errorCode: e.cause || lazy.ERRORS.UNKNOWN };
|
||||
}
|
||||
} else if (message.name == "RerunEncryption") {
|
||||
let { password } = message.data;
|
||||
|
||||
/**
|
||||
* TODO: (Bug 1901640) after enabling encryption, recreate the backup,
|
||||
* this time with sensitive data.
|
||||
*/
|
||||
return { success: true };
|
||||
} else if (message.name == "DisableEncryption") {
|
||||
try {
|
||||
await this.#bs.disableEncryption();
|
||||
await this.#bs.enableEncryption(password);
|
||||
/**
|
||||
* TODO: (Bug 1901640) after enabling encryption, recreate the backup,
|
||||
* this time with the new password.
|
||||
*/
|
||||
} catch (e) {
|
||||
/**
|
||||
* TODO: (Bug 1901308) maybe display an error if there is a problem with
|
||||
* re-encryption.
|
||||
*/
|
||||
lazy.logConsole.error(`Failed to disable encryption`, e);
|
||||
return { success: false, errorCode: e.cause || lazy.ERRORS.UNKNOWN };
|
||||
}
|
||||
/**
|
||||
* TODO: (Bug 1901640) after disabling encryption, recreate the backup,
|
||||
* this time without sensitive data.
|
||||
*/
|
||||
return { success: true };
|
||||
} else if (message.name == "RerunEncryption") {
|
||||
try {
|
||||
let { password } = message.data;
|
||||
|
||||
await this.#bs.disableEncryption();
|
||||
await this.#bs.enableEncryption(password);
|
||||
} catch (e) {
|
||||
lazy.logConsole.error(`Failed to rerun encryption`, e);
|
||||
return { success: false, errorCode: e.cause || lazy.ERRORS.UNKNOWN };
|
||||
}
|
||||
/**
|
||||
* TODO: (Bug 1901640) after enabling encryption, recreate the backup,
|
||||
* this time with the new password.
|
||||
*/
|
||||
return { success: true };
|
||||
} else if (message.name == "ShowBackupLocation") {
|
||||
this.#bs.showBackupLocation();
|
||||
} else if (message.name == "EditBackupLocation") {
|
||||
|
@ -93,44 +93,14 @@ export default class BackupSettings extends MozLitElement {
|
||||
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
|
||||
);
|
||||
|
||||
this.addEventListener("turnOnScheduledBackups", this);
|
||||
this.addEventListener("turnOffScheduledBackups", this);
|
||||
this.addEventListener("dialogCancel", this);
|
||||
this.addEventListener("getBackupFileInfo", this);
|
||||
this.addEventListener("enableEncryption", this);
|
||||
this.addEventListener("rerunEncryption", this);
|
||||
this.addEventListener("disableEncryption", this);
|
||||
this.addEventListener("restoreFromBackupConfirm", this);
|
||||
this.addEventListener("restoreFromBackupChooseFile", this);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "turnOnScheduledBackups":
|
||||
this.turnOnScheduledBackupsDialogEl.close();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:ToggleScheduledBackups", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
...event.detail,
|
||||
isScheduledBackupsEnabled: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "turnOffScheduledBackups":
|
||||
this.turnOffScheduledBackupsDialogEl.close();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:ToggleScheduledBackups", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
isScheduledBackupsEnabled: false,
|
||||
},
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "dialogCancel":
|
||||
if (this.turnOnScheduledBackupsDialogEl.open) {
|
||||
this.turnOnScheduledBackupsDialogEl.close();
|
||||
@ -175,43 +145,6 @@ export default class BackupSettings extends MozLitElement {
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "enableEncryption":
|
||||
this.enableBackupEncryptionDialogEl.close();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:ToggleEncryption", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
...event.detail,
|
||||
isEncryptionEnabled: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "rerunEncryption":
|
||||
this.enableBackupEncryptionDialogEl.close();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:RerunEncryption", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
...event.detail,
|
||||
},
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "disableEncryption":
|
||||
this.disableBackupEncryptionDialogEl.close();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:ToggleEncryption", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
isEncryptionEnabled: false,
|
||||
},
|
||||
})
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,47 +5,66 @@
|
||||
import { html } from "chrome://global/content/vendor/lit.all.mjs";
|
||||
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
|
||||
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://global/content/elements/moz-message-bar.mjs";
|
||||
|
||||
const ERROR_L10N_ID = "backup-error-retry";
|
||||
|
||||
/**
|
||||
* The widget for disabling password protection if the backup is already
|
||||
* encrypted.
|
||||
*/
|
||||
export default class DisableBackupEncryption extends MozLitElement {
|
||||
static properties = {
|
||||
// managed by BackupUIChild
|
||||
disableEncryptionErrorCode: { type: Number },
|
||||
};
|
||||
|
||||
static get queries() {
|
||||
return {
|
||||
cancelButtonEl: "#backup-disable-encryption-cancel-button",
|
||||
confirmButtonEl: "#backup-disable-encryption-confirm-button",
|
||||
errorEl: "#disable-backup-encryption-error",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the BackupUI:InitWidget custom event upon being attached to the
|
||||
* DOM, which registers with BackupUIChild for BackupService state updates.
|
||||
*/
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
|
||||
);
|
||||
constructor() {
|
||||
super();
|
||||
this.disableEncryptionErrorCode = 0;
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
close() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("dialogCancel", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.disableEncryptionErrorCode = 0;
|
||||
}
|
||||
|
||||
handleConfirm() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("disableEncryption", {
|
||||
new CustomEvent("BackupUI:DisableEncryption", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
errorTemplate() {
|
||||
return html`
|
||||
<moz-message-bar
|
||||
id="disable-backup-encryption-error"
|
||||
type="error"
|
||||
.messageL10nId="${ERROR_L10N_ID}"
|
||||
></moz-message-bar>
|
||||
`;
|
||||
}
|
||||
|
||||
contentTemplate() {
|
||||
return html`
|
||||
<div
|
||||
@ -73,12 +92,13 @@ export default class DisableBackupEncryption extends MozLitElement {
|
||||
data-l10n-id="disable-backup-encryption-support-link"
|
||||
></a>
|
||||
</div>
|
||||
${this.disableEncryptionErrorCode ? this.errorTemplate() : null}
|
||||
</main>
|
||||
|
||||
<moz-button-group id="backup-disable-encryption-button-group">
|
||||
<moz-button
|
||||
id="backup-disable-encryption-cancel-button"
|
||||
@click=${this.handleCancel}
|
||||
@click=${this.close}
|
||||
data-l10n-id="disable-backup-encryption-cancel-button"
|
||||
></moz-button>
|
||||
<moz-button
|
||||
|
@ -5,21 +5,40 @@
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { html } from "lit.all.mjs";
|
||||
import "chrome://global/content/elements/moz-card.mjs";
|
||||
import { ERRORS } from "chrome://browser/content/backup/backup-constants.mjs";
|
||||
import "./disable-backup-encryption.mjs";
|
||||
|
||||
window.MozXULElement.insertFTLIfNeeded("locales-preview/backupSettings.ftl");
|
||||
window.MozXULElement.insertFTLIfNeeded("branding/brand.ftl");
|
||||
|
||||
const SELECTABLE_ERRORS = {
|
||||
"(none)": 0,
|
||||
...ERRORS,
|
||||
};
|
||||
|
||||
export default {
|
||||
title: "Domain-specific UI Widgets/Backup/Disable Encryption",
|
||||
component: "disable-backup-encryption",
|
||||
argTypes: {},
|
||||
argTypes: {
|
||||
disableEncryptionErrorCode: {
|
||||
options: Object.keys(SELECTABLE_ERRORS),
|
||||
mapping: SELECTABLE_ERRORS,
|
||||
control: { type: "select" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = () => html`
|
||||
const Template = ({ disableEncryptionErrorCode }) => html`
|
||||
<moz-card style="width: 23.94rem;">
|
||||
<disable-backup-encryption></disable-backup-encryption>
|
||||
<disable-backup-encryption
|
||||
.disableEncryptionErrorCode=${disableEncryptionErrorCode}
|
||||
></disable-backup-encryption>
|
||||
</moz-card>
|
||||
`;
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
export const DisableError = Template.bind({});
|
||||
DisableError.args = {
|
||||
disableEncryptionErrorCode: ERRORS.UNKNOWN,
|
||||
};
|
||||
|
@ -5,9 +5,13 @@
|
||||
import { html, ifDefined } from "chrome://global/content/vendor/lit.all.mjs";
|
||||
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
|
||||
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://global/content/elements/moz-message-bar.mjs";
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://browser/content/backup/password-validation-inputs.mjs";
|
||||
|
||||
import { ERRORS } from "chrome://browser/content/backup/backup-constants.mjs";
|
||||
|
||||
/**
|
||||
* Valid attributes for the enable-backup-encryption dialog type.
|
||||
*
|
||||
@ -23,14 +27,30 @@ const VALID_L10N_IDS = new Map([
|
||||
[VALID_TYPES.CHANGE_PASSWORD, "change-backup-encryption-header"],
|
||||
]);
|
||||
|
||||
const ERROR_L10N_IDS = Object.freeze({
|
||||
[ERRORS.INVALID_PASSWORD]: "backup-error-password-requirements",
|
||||
[ERRORS.UNKNOWN]: "backup-error-retry",
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {number} errorCode Error code from backup-constants.mjs
|
||||
* @returns {string} Localization ID for error message
|
||||
*/
|
||||
function getErrorL10nId(errorCode) {
|
||||
return ERROR_L10N_IDS[errorCode] ?? ERROR_L10N_IDS[ERRORS.UNKNOWN];
|
||||
}
|
||||
|
||||
/**
|
||||
* The widget for enabling password protection if the backup is not yet
|
||||
* encrypted.
|
||||
*/
|
||||
export default class EnableBackupEncryption extends MozLitElement {
|
||||
static properties = {
|
||||
// internal state
|
||||
_inputPassValue: { type: String, state: true },
|
||||
_passwordsMatch: { type: Boolean, state: true },
|
||||
|
||||
// passed from parents
|
||||
supportBaseLink: { type: String },
|
||||
/**
|
||||
* The "type" attribute changes the layout.
|
||||
@ -38,6 +58,10 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
* @see VALID_TYPES
|
||||
*/
|
||||
type: { type: String, reflect: true },
|
||||
|
||||
// managed by BackupUIChild
|
||||
enableEncryptionErrorCode: { type: Number },
|
||||
rerunEncryptionErrorCode: { type: Number },
|
||||
};
|
||||
|
||||
static get queries() {
|
||||
@ -48,6 +72,7 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
textHeaderEl: "#backup-enable-encryption-header",
|
||||
textDescriptionEl: "#backup-enable-encryption-description",
|
||||
passwordInputsEl: "#backup-enable-encryption-password-inputs",
|
||||
errorEl: "#enable-backup-encryption-error",
|
||||
};
|
||||
}
|
||||
|
||||
@ -57,18 +82,13 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
this.type = VALID_TYPES.SET_PASSWORD;
|
||||
this._inputPassValue = "";
|
||||
this._passwordsMatch = false;
|
||||
this.enableEncryptionErrorCode = 0;
|
||||
this.rerunEncryptionErrorCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the BackupUI:InitWidget custom event upon being attached to the
|
||||
* DOM, which registers with BackupUIChild for BackupService state updates.
|
||||
*/
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
|
||||
);
|
||||
|
||||
// Listening to events from child <password-validation-inputs>
|
||||
this.addEventListener("ValidPasswordsDetected", this);
|
||||
this.addEventListener("InvalidPasswordsDetected", this);
|
||||
}
|
||||
@ -84,23 +104,29 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
}
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
close() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("dialogCancel", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
this.resetChanges();
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._inputPassValue = "";
|
||||
this._passwordsMatch = false;
|
||||
this.passwordInputsEl.reset();
|
||||
this.enableEncryptionErrorCode = 0;
|
||||
}
|
||||
|
||||
handleConfirm() {
|
||||
switch (this.type) {
|
||||
case VALID_TYPES.SET_PASSWORD:
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("enableEncryption", {
|
||||
new CustomEvent("BackupUI:EnableEncryption", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
password: this._inputPassValue,
|
||||
},
|
||||
@ -109,9 +135,8 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
break;
|
||||
case VALID_TYPES.CHANGE_PASSWORD:
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("rerunEncryption", {
|
||||
new CustomEvent("BackupUI:RerunEncryption", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
password: this._inputPassValue,
|
||||
},
|
||||
@ -119,16 +144,6 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
);
|
||||
break;
|
||||
}
|
||||
this.resetChanges();
|
||||
}
|
||||
|
||||
resetChanges() {
|
||||
this._inputPassValue = "";
|
||||
this._passwordsMatch = false;
|
||||
|
||||
this.passwordInputsEl.dispatchEvent(
|
||||
new CustomEvent("resetInputs", { bubbles: true, composed: true })
|
||||
);
|
||||
}
|
||||
|
||||
descriptionTemplate() {
|
||||
@ -155,7 +170,7 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
<moz-button-group id="backup-enable-encryption-button-group">
|
||||
<moz-button
|
||||
id="backup-enable-encryption-cancel-button"
|
||||
@click=${this.handleCancel}
|
||||
@click=${this.close}
|
||||
data-l10n-id="enable-backup-encryption-cancel-button"
|
||||
></moz-button>
|
||||
<moz-button
|
||||
@ -169,6 +184,19 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
errorTemplate() {
|
||||
let messageId = this.enableEncryptionErrorCode
|
||||
? getErrorL10nId(this.enableEncryptionErrorCode)
|
||||
: getErrorL10nId(this.rerunEncryptionErrorCode);
|
||||
return html`
|
||||
<moz-message-bar
|
||||
id="enable-backup-encryption-error"
|
||||
type="error"
|
||||
.messageL10nId="${messageId}"
|
||||
></moz-message-bar>
|
||||
`;
|
||||
}
|
||||
|
||||
contentTemplate() {
|
||||
return html`
|
||||
<div
|
||||
@ -190,6 +218,10 @@ export default class EnableBackupEncryption extends MozLitElement {
|
||||
.supportBaseLink=${this.supportBaseLink}
|
||||
>
|
||||
</password-validation-inputs>
|
||||
|
||||
${this.enableEncryptionErrorCode || this.rerunEncryptionErrorCode
|
||||
? this.errorTemplate()
|
||||
: null}
|
||||
</div>
|
||||
${this.buttonGroupTemplate()}
|
||||
</div>
|
||||
|
@ -5,11 +5,17 @@
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { html } from "lit.all.mjs";
|
||||
import "chrome://global/content/elements/moz-card.mjs";
|
||||
import { ERRORS } from "chrome://browser/content/backup/backup-constants.mjs";
|
||||
import "./enable-backup-encryption.mjs";
|
||||
|
||||
window.MozXULElement.insertFTLIfNeeded("locales-preview/backupSettings.ftl");
|
||||
window.MozXULElement.insertFTLIfNeeded("branding/brand.ftl");
|
||||
|
||||
const SELECTABLE_ERRORS = {
|
||||
"(none)": 0,
|
||||
...ERRORS,
|
||||
};
|
||||
|
||||
export default {
|
||||
title: "Domain-specific UI Widgets/Backup/Enable Encryption",
|
||||
component: "enable-backup-encryption",
|
||||
@ -18,12 +24,30 @@ export default {
|
||||
control: { type: "select" },
|
||||
options: ["set-password", "change-password"],
|
||||
},
|
||||
enableEncryptionErrorCode: {
|
||||
options: Object.keys(SELECTABLE_ERRORS),
|
||||
mapping: SELECTABLE_ERRORS,
|
||||
control: { type: "select" },
|
||||
},
|
||||
rerunEncryptionErrorCode: {
|
||||
options: Object.keys(SELECTABLE_ERRORS),
|
||||
mapping: SELECTABLE_ERRORS,
|
||||
control: { type: "select" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = ({ type }) => html`
|
||||
const Template = ({
|
||||
type,
|
||||
enableEncryptionErrorCode,
|
||||
rerunEncryptionErrorCode,
|
||||
}) => html`
|
||||
<moz-card style="width: 23.94rem; position: relative;">
|
||||
<enable-backup-encryption type=${type}></enable-backup-encryption>
|
||||
<enable-backup-encryption
|
||||
type=${type}
|
||||
.enableEncryptionErrorCode=${enableEncryptionErrorCode}
|
||||
.rerunEncryptionErrorCode=${rerunEncryptionErrorCode}
|
||||
></enable-backup-encryption>
|
||||
</moz-card>
|
||||
`;
|
||||
|
||||
@ -36,3 +60,15 @@ export const ChangePassword = Template.bind({});
|
||||
ChangePassword.args = {
|
||||
type: "change-password",
|
||||
};
|
||||
|
||||
export const SetPasswordError = Template.bind({});
|
||||
SetPasswordError.args = {
|
||||
type: "set-password",
|
||||
enableEncryptionErrorCode: ERRORS.INVALID_PASSWORD,
|
||||
};
|
||||
|
||||
export const ChangePasswordError = Template.bind({});
|
||||
ChangePasswordError.args = {
|
||||
type: "change-password",
|
||||
rerunEncryptionErrorCode: ERRORS.INVALID_PASSWORD,
|
||||
};
|
||||
|
@ -48,17 +48,7 @@ export default class PasswordValidationInputs extends MozLitElement {
|
||||
this._tooltipFocus = false;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.addEventListener("resetInputs", this.handleReset);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.removeEventListener("resetInputs", this.handleReset);
|
||||
}
|
||||
|
||||
handleReset() {
|
||||
reset() {
|
||||
this.formEl.reset();
|
||||
this._showRules = false;
|
||||
this._hasCommon = false;
|
||||
|
@ -17,18 +17,7 @@ export default class TurnOffScheduledBackups extends MozLitElement {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the BackupUI:InitWidget custom event upon being attached to the
|
||||
* DOM, which registers with BackupUIChild for BackupService state updates.
|
||||
*/
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
|
||||
);
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
close() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("dialogCancel", {
|
||||
bubbles: true,
|
||||
@ -39,9 +28,8 @@ export default class TurnOffScheduledBackups extends MozLitElement {
|
||||
|
||||
handleConfirm() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("turnOffScheduledBackups", {
|
||||
new CustomEvent("BackupUI:DisableScheduledBackups", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -77,7 +65,7 @@ export default class TurnOffScheduledBackups extends MozLitElement {
|
||||
<moz-button-group id="backup-turn-off-scheduled-button-group">
|
||||
<moz-button
|
||||
id="backup-turn-off-scheduled-cancel-button"
|
||||
@click=${this.handleCancel}
|
||||
@click=${this.close}
|
||||
data-l10n-id="turn-off-scheduled-backups-cancel-button"
|
||||
></moz-button>
|
||||
<moz-button
|
||||
|
@ -5,9 +5,29 @@
|
||||
import { html } from "chrome://global/content/vendor/lit.all.mjs";
|
||||
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
|
||||
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://global/content/elements/moz-message-bar.mjs";
|
||||
// eslint-disable-next-line import/no-unassigned-import
|
||||
import "chrome://browser/content/backup/password-validation-inputs.mjs";
|
||||
|
||||
import { ERRORS } from "chrome://browser/content/backup/backup-constants.mjs";
|
||||
|
||||
const ENABLE_ERROR_L10N_IDS = Object.freeze({
|
||||
[ERRORS.FILE_SYSTEM_ERROR]: "turn-on-scheduled-backups-error-file-system",
|
||||
[ERRORS.INVALID_PASSWORD]: "backup-error-password-requirements",
|
||||
[ERRORS.UNKNOWN]: "backup-error-retry",
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {number} errorCode Error code from backup-constants.mjs
|
||||
* @returns {string} Localization ID for error message
|
||||
*/
|
||||
function getEnableErrorL10nId(errorCode) {
|
||||
return (
|
||||
ENABLE_ERROR_L10N_IDS[errorCode] ?? ENABLE_ERROR_L10N_IDS[ERRORS.UNKNOWN]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The widget for showing available options when users want to turn on
|
||||
* scheduled backups.
|
||||
@ -16,16 +36,22 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
#placeholderIconURL = "chrome://global/skin/icons/page-portrait.svg";
|
||||
|
||||
static properties = {
|
||||
// passed in from parents
|
||||
defaultIconURL: { type: String, reflect: true },
|
||||
defaultLabel: { type: String, reflect: true },
|
||||
defaultPath: { type: String, reflect: true },
|
||||
_newIconURL: { type: String },
|
||||
_newLabel: { type: String },
|
||||
_newPath: { type: String },
|
||||
supportBaseLink: { type: String },
|
||||
|
||||
// internal state
|
||||
_newIconURL: { type: String, state: true },
|
||||
_newLabel: { type: String, state: true },
|
||||
_newPath: { type: String, state: true },
|
||||
_showPasswordOptions: { type: Boolean, reflect: true, state: true },
|
||||
_passwordsMatch: { type: Boolean, state: true },
|
||||
_inputPassValue: { type: String, state: true },
|
||||
supportBaseLink: { type: String },
|
||||
|
||||
// managed by BackupUIChild
|
||||
enableBackupErrorCode: { type: Number },
|
||||
};
|
||||
|
||||
static get queries() {
|
||||
@ -37,6 +63,7 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
filePathInputDefaultEl: "#backup-location-filepicker-input-default",
|
||||
passwordOptionsCheckboxEl: "#sensitive-data-checkbox-input",
|
||||
passwordOptionsExpandedEl: "#passwords",
|
||||
errorEl: "#enable-backup-encryption-error",
|
||||
};
|
||||
}
|
||||
|
||||
@ -50,19 +77,19 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
this._newPath = "";
|
||||
this._showPasswordOptions = false;
|
||||
this._passwordsMatch = false;
|
||||
this.enableBackupErrorCode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches the BackupUI:InitWidget custom event upon being attached to the
|
||||
* DOM, which registers with BackupUIChild for BackupService state updates.
|
||||
*/
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("BackupUI:InitWidget", { bubbles: true })
|
||||
);
|
||||
|
||||
// listen to events from BackupUIChild
|
||||
this.addEventListener("BackupUI:SelectNewFilepickerPath", this);
|
||||
|
||||
// listen to events from <password-validation-inputs>
|
||||
this.addEventListener("ValidPasswordsDetected", this);
|
||||
this.addEventListener("InvalidPasswordsDetected", this);
|
||||
}
|
||||
@ -94,14 +121,14 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
);
|
||||
}
|
||||
|
||||
handleCancel() {
|
||||
close() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("dialogCancel", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
this.resetChanges();
|
||||
this.reset();
|
||||
}
|
||||
|
||||
handleConfirm() {
|
||||
@ -114,13 +141,11 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
}
|
||||
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("turnOnScheduledBackups", {
|
||||
new CustomEvent("BackupUI:EnableScheduledBackups", {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail,
|
||||
})
|
||||
);
|
||||
this.resetChanges();
|
||||
}
|
||||
|
||||
handleTogglePasswordOptions() {
|
||||
@ -128,7 +153,7 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
this._passwordsMatch = false;
|
||||
}
|
||||
|
||||
resetChanges() {
|
||||
reset() {
|
||||
this._newPath = "";
|
||||
this._newIconURL = "";
|
||||
this._newLabel = "";
|
||||
@ -136,11 +161,12 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
this.passwordOptionsCheckboxEl.checked = false;
|
||||
this._passwordsMatch = false;
|
||||
this._inputPassValue = "";
|
||||
this.enableBackupErrorCode = 0;
|
||||
|
||||
if (this.passwordOptionsExpandedEl) {
|
||||
this.passwordOptionsExpandedEl.dispatchEvent(
|
||||
new CustomEvent("resetInputs", { bubbles: true, composed: true })
|
||||
);
|
||||
/** @type {import("./password-validation-inputs.mjs").default} */
|
||||
const passwordElement = this.passwordOptionsExpandedEl;
|
||||
passwordElement.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,6 +206,16 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
errorTemplate() {
|
||||
return html`
|
||||
<moz-message-bar
|
||||
id="enable-backup-encryption-error"
|
||||
type="error"
|
||||
.messageL10nId="${getEnableErrorL10nId(this.enableBackupErrorCode)}"
|
||||
></moz-message-bar>
|
||||
`;
|
||||
}
|
||||
|
||||
allOptionsTemplate() {
|
||||
return html`
|
||||
<fieldset id="all-controls">
|
||||
@ -269,12 +305,13 @@ export default class TurnOnScheduledBackups extends MozLitElement {
|
||||
></a>
|
||||
</div>
|
||||
${this.allOptionsTemplate()}
|
||||
${this.enableBackupErrorCode ? this.errorTemplate() : null}
|
||||
</main>
|
||||
|
||||
<moz-button-group id="backup-turn-on-scheduled-button-group">
|
||||
<moz-button
|
||||
id="backup-turn-on-scheduled-cancel-button"
|
||||
@click=${this.handleCancel}
|
||||
@click=${this.close}
|
||||
data-l10n-id="turn-on-scheduled-backups-cancel-button"
|
||||
></moz-button>
|
||||
<moz-button
|
||||
|
@ -5,24 +5,43 @@
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { html, ifDefined } from "lit.all.mjs";
|
||||
import "chrome://global/content/elements/moz-card.mjs";
|
||||
import { ERRORS } from "chrome://browser/content/backup/backup-constants.mjs";
|
||||
import "./turn-on-scheduled-backups.mjs";
|
||||
|
||||
window.MozXULElement.insertFTLIfNeeded("locales-preview/backupSettings.ftl");
|
||||
window.MozXULElement.insertFTLIfNeeded("branding/brand.ftl");
|
||||
|
||||
const SELECTABLE_ERRORS = {
|
||||
"(none)": 0,
|
||||
...ERRORS,
|
||||
};
|
||||
|
||||
export default {
|
||||
title: "Domain-specific UI Widgets/Backup/Turn On Scheduled Backups",
|
||||
component: "turn-on-scheduled-backups",
|
||||
argTypes: {},
|
||||
argTypes: {
|
||||
enableBackupErrorCode: {
|
||||
options: Object.keys(SELECTABLE_ERRORS),
|
||||
mapping: SELECTABLE_ERRORS,
|
||||
control: { type: "select" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = ({ defaultPath, _newPath, defaultLabel, _newLabel }) => html`
|
||||
const Template = ({
|
||||
defaultPath,
|
||||
_newPath,
|
||||
defaultLabel,
|
||||
_newLabel,
|
||||
enableBackupErrorCode,
|
||||
}) => html`
|
||||
<moz-card style="width: 27.8rem; position: relative;">
|
||||
<turn-on-scheduled-backups
|
||||
defaultPath=${defaultPath}
|
||||
_newPath=${ifDefined(_newPath)}
|
||||
defaultLabel=${defaultLabel}
|
||||
_newLabel=${ifDefined(_newLabel)}
|
||||
.enableBackupErrorCode=${enableBackupErrorCode}
|
||||
></turn-on-scheduled-backups>
|
||||
</moz-card>
|
||||
`;
|
||||
@ -39,3 +58,9 @@ CustomLocation.args = {
|
||||
_newPath: "/Some/Test/Custom/Dir",
|
||||
_newLabel: "Dir",
|
||||
};
|
||||
|
||||
export const EnableError = Template.bind({});
|
||||
EnableError.args = {
|
||||
...CustomLocation.args,
|
||||
enableBackupErrorCode: ERRORS.FILE_SYSTEM_ERROR,
|
||||
};
|
||||
|
@ -99,7 +99,10 @@ add_task(async function test_disable_backup_encryption_confirm() {
|
||||
);
|
||||
|
||||
let confirmButton = disableBackupEncryption.confirmButtonEl;
|
||||
let promise = BrowserTestUtils.waitForEvent(window, "disableEncryption");
|
||||
let promise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"BackupUI:DisableEncryption"
|
||||
);
|
||||
|
||||
Assert.ok(confirmButton, "Confirm button should be found");
|
||||
|
||||
|
@ -91,7 +91,7 @@ add_task(async function test_enable_backup_encryption_checkbox_confirm() {
|
||||
|
||||
let encryptionPromise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"enableEncryption"
|
||||
"BackupUI:EnableEncryption"
|
||||
);
|
||||
|
||||
confirmButton.click();
|
||||
@ -185,7 +185,10 @@ add_task(
|
||||
await settings.updateComplete;
|
||||
confirmButton = settings.enableBackupEncryptionEl.confirmButtonEl;
|
||||
|
||||
let promise = BrowserTestUtils.waitForEvent(window, "rerunEncryption");
|
||||
let promise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"BackupUI:RerunEncryption"
|
||||
);
|
||||
confirmButton.click();
|
||||
await promise;
|
||||
|
||||
|
@ -37,7 +37,7 @@ async function turnOffScheduledBackupsHelper(browser, taskFn) {
|
||||
let confirmButton = turnOffScheduledBackups.confirmButtonEl;
|
||||
let promise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"turnOffScheduledBackups"
|
||||
"BackupUI:DisableScheduledBackups"
|
||||
);
|
||||
|
||||
Assert.ok(confirmButton, "Confirm button should be found");
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const { ERRORS } = ChromeUtils.importESModule(
|
||||
"chrome://browser/content/backup/backup-constants.mjs"
|
||||
);
|
||||
|
||||
const SCHEDULED_BACKUPS_ENABLED_PREF = "browser.backup.scheduled.enabled";
|
||||
|
||||
add_setup(async () => {
|
||||
@ -43,7 +47,7 @@ add_task(async function test_turn_on_scheduled_backups_confirm() {
|
||||
let confirmButton = turnOnScheduledBackups.confirmButtonEl;
|
||||
let promise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"turnOnScheduledBackups"
|
||||
"BackupUI:EnableScheduledBackups"
|
||||
);
|
||||
|
||||
Assert.ok(confirmButton, "Confirm button should be found");
|
||||
@ -86,6 +90,7 @@ add_task(async function test_turn_on_custom_location_filepicker() {
|
||||
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
||||
|
||||
// After setting up mocks, start testing components
|
||||
/** @type {import("../../content/backup-settings.mjs").default} */
|
||||
let settings = browser.contentDocument.querySelector("backup-settings");
|
||||
let turnOnButton = settings.scheduledBackupsButtonEl;
|
||||
|
||||
@ -148,7 +153,7 @@ add_task(async function test_turn_on_custom_location_filepicker() {
|
||||
|
||||
let confirmButtonPromise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"turnOnScheduledBackups"
|
||||
"BackupUI:EnableScheduledBackups"
|
||||
);
|
||||
|
||||
confirmButton.click();
|
||||
@ -234,7 +239,7 @@ add_task(async function test_turn_on_scheduled_backups_encryption() {
|
||||
|
||||
let promise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"turnOnScheduledBackups"
|
||||
"BackupUI:EnableScheduledBackups"
|
||||
);
|
||||
|
||||
confirmButton.click();
|
||||
@ -280,7 +285,7 @@ add_task(async function test_turn_on_scheduled_backups_encryption_error() {
|
||||
|
||||
let encryptionStub = sandbox
|
||||
.stub(BackupService.prototype, "enableEncryption")
|
||||
.throws();
|
||||
.throws(new Error("test error", { cause: ERRORS.INVALID_PASSWORD }));
|
||||
|
||||
// Enable passwords
|
||||
let passwordsCheckbox = turnOnScheduledBackups.passwordOptionsCheckboxEl;
|
||||
@ -317,7 +322,7 @@ add_task(async function test_turn_on_scheduled_backups_encryption_error() {
|
||||
|
||||
let promise = BrowserTestUtils.waitForEvent(
|
||||
window,
|
||||
"turnOnScheduledBackups"
|
||||
"BackupUI:EnableScheduledBackups"
|
||||
);
|
||||
|
||||
confirmButton.click();
|
||||
@ -339,6 +344,16 @@ add_task(async function test_turn_on_scheduled_backups_encryption_error() {
|
||||
"Scheduled backups pref should still be false"
|
||||
);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
() => !!turnOnScheduledBackups.errorEl,
|
||||
"Error should be displayed to the user"
|
||||
);
|
||||
|
||||
Assert.ok(
|
||||
turnOnScheduledBackups.errorEl,
|
||||
"Error should be displayed to the user"
|
||||
);
|
||||
|
||||
sandbox.restore();
|
||||
Services.prefs.clearUserPref(SCHEDULED_BACKUPS_ENABLED_PREF);
|
||||
});
|
||||
|
@ -9,6 +9,7 @@ const { BackupService } = ChromeUtils.importESModule(
|
||||
|
||||
const { MockFilePicker } = SpecialPowers;
|
||||
|
||||
/** @type {{sinon: import("@types/sinon").SinonApi}} */
|
||||
const { sinon } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/Sinon.sys.mjs"
|
||||
);
|
||||
|
@ -16,22 +16,6 @@
|
||||
"resource://testing-common/BrowserTestUtils.sys.mjs"
|
||||
);
|
||||
|
||||
/**
|
||||
* Tests that adding a disable-backup-encryption element to the DOM causes it to
|
||||
* fire a BackupUI:InitWidget event.
|
||||
*/
|
||||
add_task(async function test_initWidget() {
|
||||
let disableBackupEncryption = document.createElement("disable-backup-encryption");
|
||||
let content = document.getElementById("content");
|
||||
|
||||
let sawInitWidget = BrowserTestUtils.waitForEvent(content, "BackupUI:InitWidget");
|
||||
content.appendChild(disableBackupEncryption);
|
||||
await sawInitWidget;
|
||||
ok(true, "Saw BackupUI:InitWidget");
|
||||
|
||||
disableBackupEncryption.remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that pressing the confirm button will dispatch the expected events.
|
||||
*/
|
||||
@ -42,7 +26,7 @@
|
||||
ok(confirmButton, "Confirm button should be found");
|
||||
|
||||
let content = document.getElementById("content");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "disableEncryption");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "BackupUI:DisableEncryption");
|
||||
|
||||
confirmButton.click()
|
||||
|
||||
|
@ -17,22 +17,6 @@
|
||||
"resource://testing-common/BrowserTestUtils.sys.mjs"
|
||||
);
|
||||
|
||||
/**
|
||||
* Tests that adding a enable-backup-encryption element to the DOM causes it to
|
||||
* fire a BackupUI:InitWidget event.
|
||||
*/
|
||||
add_task(async function test_initWidget() {
|
||||
let enableBackupEncryption = document.createElement("enable-backup-encryption");
|
||||
let content = document.getElementById("content");
|
||||
|
||||
let sawInitWidget = BrowserTestUtils.waitForEvent(content, "BackupUI:InitWidget");
|
||||
content.appendChild(enableBackupEncryption);
|
||||
await sawInitWidget;
|
||||
ok(true, "Saw BackupUI:InitWidget");
|
||||
|
||||
enableBackupEncryption.remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that pressing the confirm button for the set-password type dialog will dispatch the expected events.
|
||||
*/
|
||||
@ -61,12 +45,14 @@
|
||||
ok(!confirmButton.disabled, "Confirm button should no longer be disabled");
|
||||
|
||||
let content = document.getElementById("content");
|
||||
let encryptionPromise = BrowserTestUtils.waitForEvent(content, "enableEncryption");
|
||||
let encryptionPromise = BrowserTestUtils.waitForEvent(content, "BackupUI:EnableEncryption");
|
||||
|
||||
confirmButton.click()
|
||||
|
||||
await encryptionPromise;
|
||||
ok(true, "Detected event after selecting the confirm button");
|
||||
|
||||
enableBackupEncryption.reset();
|
||||
})
|
||||
|
||||
/**
|
||||
@ -99,12 +85,14 @@
|
||||
ok(!confirmButton.disabled, "Confirm button should no longer be disabled");
|
||||
|
||||
let content = document.getElementById("content");
|
||||
let encryptionPromise = BrowserTestUtils.waitForEvent(content, "rerunEncryption");
|
||||
let encryptionPromise = BrowserTestUtils.waitForEvent(content, "BackupUI:RerunEncryption");
|
||||
|
||||
confirmButton.click()
|
||||
|
||||
await encryptionPromise;
|
||||
ok(true, "Detected event after selecting the confirm button");
|
||||
|
||||
enableBackupEncryption.reset();
|
||||
})
|
||||
|
||||
/**
|
||||
@ -126,6 +114,8 @@
|
||||
|
||||
await promise;
|
||||
ok(true, "Detected event after selecting the cancel button");
|
||||
|
||||
enableBackupEncryption.reset();
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
|
@ -16,22 +16,6 @@
|
||||
"resource://testing-common/BrowserTestUtils.sys.mjs"
|
||||
);
|
||||
|
||||
/**
|
||||
* Tests that adding a turn-off-scheduled-backups element to the DOM causes it to
|
||||
* fire a BackupUI:InitWidget event.
|
||||
*/
|
||||
add_task(async function test_initWidget() {
|
||||
let turnOffScheduledBackups = document.createElement("turn-off-scheduled-backups");
|
||||
let content = document.getElementById("content");
|
||||
|
||||
let sawInitWidget = BrowserTestUtils.waitForEvent(content, "BackupUI:InitWidget");
|
||||
content.appendChild(turnOffScheduledBackups);
|
||||
await sawInitWidget;
|
||||
ok(true, "Saw BackupUI:InitWidget");
|
||||
|
||||
turnOffScheduledBackups.remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that pressing the confirm button will dispatch the expected events.
|
||||
*/
|
||||
@ -42,7 +26,7 @@
|
||||
ok(confirmButton, "Confirm button should be found");
|
||||
|
||||
let content = document.getElementById("content");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "turnOffScheduledBackups");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "BackupUI:DisableScheduledBackups");
|
||||
|
||||
confirmButton.click()
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
||||
ok(confirmButton, "Confirm button should be found");
|
||||
|
||||
let content = document.getElementById("content");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "turnOnScheduledBackups");
|
||||
let promise = BrowserTestUtils.waitForEvent(content, "BackupUI:EnableScheduledBackups");
|
||||
|
||||
confirmButton.click()
|
||||
|
||||
|
@ -81,6 +81,10 @@ turn-on-scheduled-backups-encryption-repeat-password-label = Repeat password
|
||||
turn-on-scheduled-backups-cancel-button = Cancel
|
||||
turn-on-scheduled-backups-confirm-button = Turn on backup
|
||||
|
||||
# Tell the user there was an error accessing the user's selected backup
|
||||
# folder. The folder may be invalid or inaccessible.
|
||||
turn-on-scheduled-backups-error-file-system = There was a problem with your selected backup folder. Choose a different folder and try again.
|
||||
|
||||
## These strings are displayed in a modal when users want to turn off scheduled backups.
|
||||
|
||||
turn-off-scheduled-backups-header = Turn off backup?
|
||||
@ -195,6 +199,17 @@ disable-backup-encryption-support-link = What will be backed up?
|
||||
disable-backup-encryption-cancel-button = Cancel
|
||||
disable-backup-encryption-confirm-button = Remove password
|
||||
|
||||
## These strings are used to tell users when errors occur when using
|
||||
## the backup system
|
||||
|
||||
backup-error-password-requirements = Your password doesn’t meet the requirements. Please try another password.
|
||||
|
||||
# This error message will be shown to the user when something went wrong with
|
||||
# the backup system but we do not have any more specific idea of what went
|
||||
# wrong. This message invites the user to try an action again because there
|
||||
# is a chance that the action will succeed if retried.
|
||||
backup-error-retry = Something went wrong. Please try again.
|
||||
|
||||
## These strings are inserted into the generated single-file backup archive.
|
||||
## The single-file backup archive is a specially-crafted, static HTML file
|
||||
## that is placed within a user specified directory (the Documents folder by
|
||||
|
Loading…
Reference in New Issue
Block a user