commit 9c6fac590c320c4d27b94fd7d48ddfe43198708b
parent f30cf7c5e8dd019bee8c5aac10c8975e6529f67a
Author: Jason Prickett <jprickett@mozilla.com>
Date: Thu, 9 Oct 2025 17:14:59 +0000
Bug 1993126 - Display backup file info underneath input when file is selected r=omc-reviewers,sthompson,mviar
Differential Revision: https://phabricator.services.mozilla.com/D267987
Diffstat:
5 files changed, 101 insertions(+), 2 deletions(-)
diff --git a/browser/components/backup/BackupService.sys.mjs b/browser/components/backup/BackupService.sys.mjs
@@ -2623,6 +2623,7 @@ export class BackupService extends EventTarget {
appVersion: AppConstants.MOZ_APP_VERSION,
buildID: AppConstants.MOZ_BUILDID,
profileName,
+ deviceName: Services.sysinfo.get("device") || Services.dns.myHostName,
machineName: lazy.fxAccounts.device.getLocalName(),
osName: Services.sysinfo.getProperty("name"),
osVersion: Services.sysinfo.getProperty("version"),
@@ -3784,6 +3785,7 @@ export class BackupService extends EventTarget {
this.#_state.backupFileInfo = {
isEncrypted,
date: archiveJSON?.meta?.date,
+ deviceName: archiveJSON?.meta?.deviceName,
};
this.#_state.backupFileToRestore = backupFilePath;
this.stateUpdate();
diff --git a/browser/components/backup/content/restore-from-backup.css b/browser/components/backup/content/restore-from-backup.css
@@ -94,6 +94,13 @@
#backup-filepicker-button {
margin-block: var(--space-xsmall);
}
+
+ #restore-from-backup-backup-found-info {
+ text-align: start;
+ color: var(--text-color-deemphasized);
+ font-size: var(--font-size-small);
+ margin-top: var(--space-xsmall);
+ }
}
#backup-password {
diff --git a/browser/components/backup/content/restore-from-backup.mjs b/browser/components/backup/content/restore-from-backup.mjs
@@ -253,6 +253,21 @@ export default class RestoreFromBackup extends MozLitElement {
data-l10n-id="restore-from-backup-no-backup-file-link"
></a>`
: null}
+ ${this.backupServiceState?.backupFileInfo
+ ? html`<p
+ id="restore-from-backup-backup-found-info"
+ data-l10n-id="backup-file-creation-date-and-device"
+ data-l10n-args=${JSON.stringify({
+ machineName:
+ this.backupServiceState.backupFileInfo.deviceName ?? "",
+ date: this.backupServiceState.backupFileInfo.date
+ ? new Date(
+ this.backupServiceState.backupFileInfo.date
+ ).getTime()
+ : 0,
+ })}
+ ></p>`
+ : null}
</fieldset>
<fieldset id="password-entry-controls">
diff --git a/browser/components/backup/tests/browser/browser_settings_restore_from_backup.js b/browser/components/backup/tests/browser/browser_settings_restore_from_backup.js
@@ -107,6 +107,7 @@ add_task(async function test_restore_from_backup() {
...restoreFromBackup.backupServiceState,
backupFileInfo: {
date: new Date(),
+ deviceName: "test-device",
isEncrypted: true,
},
};
@@ -368,3 +369,72 @@ add_task(
);
}
);
+
+/**
+ * Tests that the backup file info is displayed when backupFileInfo is present
+ */
+add_task(async function test_restore_backup_file_info_display() {
+ await BrowserTestUtils.withNewTab("about:preferences#sync", async browser => {
+ let settings = browser.contentDocument.querySelector("backup-settings");
+ await settings.updateComplete;
+
+ Assert.ok(
+ settings.restoreFromBackupButtonEl,
+ "Restore button should exist"
+ );
+
+ settings.restoreFromBackupButtonEl.click();
+ await settings.updateComplete;
+
+ let restoreFromBackup = settings.restoreFromBackupEl;
+ Assert.ok(restoreFromBackup, "restore-from-backup should be found");
+
+ // Initially, backup file info should not be displayed underneath the input
+ let fileInfoSpan = restoreFromBackup.shadowRoot.querySelector(
+ "#restore-from-backup-backup-found-info"
+ );
+ Assert.ok(
+ !fileInfoSpan,
+ "Backup file info should not be displayed when backupFileInfo is null"
+ );
+
+ // Set backup file info with device name and date
+ const mockDate = new Date("2025-10-07T21:27:56.844Z");
+ const mockDeviceName = "test-device";
+ restoreFromBackup.backupServiceState = {
+ ...restoreFromBackup.backupServiceState,
+ backupFileInfo: {
+ date: mockDate,
+ deviceName: mockDeviceName,
+ isEncrypted: false,
+ },
+ };
+ await restoreFromBackup.updateComplete;
+
+ fileInfoSpan = restoreFromBackup.shadowRoot.querySelector(
+ "#restore-from-backup-backup-found-info"
+ );
+ Assert.ok(
+ fileInfoSpan,
+ "Backup file info should be displayed when backupFileInfo is set"
+ );
+
+ Assert.equal(
+ fileInfoSpan.getAttribute("data-l10n-id"),
+ "backup-file-creation-date-and-device",
+ "Should have the correct l10n id"
+ );
+
+ const l10nArgs = JSON.parse(fileInfoSpan.getAttribute("data-l10n-args"));
+ Assert.equal(
+ l10nArgs.machineName,
+ mockDeviceName,
+ "l10n args should contain the correct device name"
+ );
+ Assert.equal(
+ l10nArgs.date,
+ mockDate.getTime(),
+ "l10n args should contain the correct date"
+ );
+ });
+});
diff --git a/browser/components/backup/tests/xpcshell/test_BackupService.js b/browser/components/backup/tests/xpcshell/test_BackupService.js
@@ -856,12 +856,17 @@ add_task(async function test_getBackupFileInfo() {
const DATE = "2024-06-25T21:59:11.777Z";
const IS_ENCRYPTED = true;
+ const DEVICE_NAME = "test-device";
let fakeSampleArchiveResult = {
isEncrypted: IS_ENCRYPTED,
startByteOffset: 26985,
contentType: "multipart/mixed",
- archiveJSON: { version: 1, meta: { date: DATE }, encConfig: {} },
+ archiveJSON: {
+ version: 1,
+ meta: { date: DATE, deviceName: DEVICE_NAME },
+ encConfig: {},
+ },
};
sandbox
@@ -879,7 +884,7 @@ add_task(async function test_getBackupFileInfo() {
Assert.deepEqual(
bs.state.backupFileInfo,
- { isEncrypted: IS_ENCRYPTED, date: DATE },
+ { isEncrypted: IS_ENCRYPTED, date: DATE, deviceName: DEVICE_NAME },
"State should match a subset from the archive sample."
);