Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* Any copyright is dedicated to the Public Domain.
"use strict";
/* import-globals-from ../../../../../toolkit/profile/test/xpcshell/head.js */
/* import-globals-from ../../../profiles/tests/unit/head.js */
const { SelectableProfileBackupResource } = ChromeUtils.importESModule(
"resource:///modules/backup/SelectableProfileBackupResource.sys.mjs"
);
const { ProfilesDatastoreService } = ChromeUtils.importESModule(
"moz-src:///toolkit/profile/ProfilesDatastoreService.sys.mjs"
);
const SELECTABLE_PROFILE_STAGING_FOLDER_NAME = "selectable_profile_metadata";
const SELECTABLE_PROFILE_METADATA_FILE_NAME = "profile_metadata.json";
add_setup(async function () {
await initSelectableProfileService();
});
/**
* Tests backup and recover of profile metadata with a default avatar.
*/
add_task(async function test_backup_and_recover_with_default_avatar() {
let sandbox = sinon.createSandbox();
const SelectableProfileService = getSelectableProfileService();
sandbox
.stub(SelectableProfileService, "getAllProfiles")
.returns([{ id: 202, name: "Profile 1" }]);
let originalProfile = SelectableProfileService.currentProfile;
// Set up the original profile with test data
originalProfile.name = "Original Profile";
await originalProfile.setAvatar("book");
await updateNotified();
let stagingPath = await IOUtils.createUniqueDirectory(
PathUtils.tempDir,
"SelectableProfileBackupResource-staging-test"
);
// Backup the original profile
let resource = new SelectableProfileBackupResource();
let manifestEntry = await resource.backup(stagingPath, originalProfile.path);
Assert.equal(manifestEntry, null, "Should return null manifest entry");
// Verify backup files exist
let metadataPath = PathUtils.join(
stagingPath,
SELECTABLE_PROFILE_STAGING_FOLDER_NAME,
SELECTABLE_PROFILE_METADATA_FILE_NAME
);
Assert.ok(await IOUtils.exists(metadataPath), "Metadata file should exist");
let metadata = await IOUtils.readJSON(metadataPath);
Assert.equal(
metadata.name,
"Original Profile",
"Backed up name should match"
);
Assert.equal(metadata.avatar, "book", "Backed up avatar should match");
Assert.ok(metadata.theme, "Theme should be present");
// Create a second profile to recover into
let targetProfile = await createTestProfile({ name: "Target Profile" });
// Modify target profile to have different data before recovery
targetProfile.name = "Target Profile Before Recovery";
await targetProfile.setAvatar("star");
await updateNotified();
Assert.equal(targetProfile.name, "Target Profile Before Recovery");
Assert.equal(targetProfile.avatar, "star");
// Recover into the target profile
let postRecoveryEntry = await resource.recover(
null,
stagingPath,
targetProfile.path
);
// Let's refetch the profile to get the most up to date information
targetProfile = await SelectableProfileService.getProfile(targetProfile.id);
Assert.equal(
postRecoveryEntry,
null,
"Should return null as post recovery entry"
);
// Verify the target profile now has the original profile's data
Assert.equal(
targetProfile.name,
originalProfile.name,
"Recovered profile name should match original"
);
Assert.equal(
targetProfile.avatar,
originalProfile.avatar,
"Recovered profile avatar should match original"
);
await maybeRemovePath(stagingPath);
sandbox.restore();
});
/**
* Tests backup and recover of profile metadata with a custom avatar.
*/
add_task(async function test_backup_and_recover_with_custom_avatar() {
let sandbox = sinon.createSandbox();
const SelectableProfileService = getSelectableProfileService();
sandbox
.stub(SelectableProfileService, "getAllProfiles")
.returns([{ id: 202, name: "Profile 1" }]);
let originalProfile = SelectableProfileService.currentProfile;
// Set up the original profile with a custom avatar
originalProfile.name = "Custom Avatar Profile";
let testAvatarPath = do_get_file("data/fake_avatar.png").path;
let avatarFile = await File.createFromFileName(testAvatarPath);
await originalProfile.setAvatar(avatarFile);
await updateNotified();
Assert.ok(
originalProfile.hasCustomAvatar,
"Original should have custom avatar"
);
let originalAvatarName = originalProfile.avatar;
let stagingPath = await IOUtils.createUniqueDirectory(
PathUtils.tempDir,
"SelectableProfileBackupResource-staging-test"
);
// Backup the original profile
let resource = new SelectableProfileBackupResource();
let manifestEntry = await resource.backup(stagingPath, originalProfile.path);
Assert.equal(manifestEntry, null, "Should return null manifest entry");
// Verify backup files exist
let metadataPath = PathUtils.join(
stagingPath,
SELECTABLE_PROFILE_STAGING_FOLDER_NAME,
SELECTABLE_PROFILE_METADATA_FILE_NAME
);
Assert.ok(await IOUtils.exists(metadataPath), "Metadata file should exist");
let metadata = await IOUtils.readJSON(metadataPath);
Assert.equal(
metadata.name,
"Custom Avatar Profile",
"Backed up name should match"
);
Assert.equal(
metadata.avatar,
originalAvatarName,
"Backed up avatar should match"
);
// Verify custom avatar file was copied to staging
let copiedAvatarPath = PathUtils.join(
stagingPath,
SELECTABLE_PROFILE_STAGING_FOLDER_NAME,
originalAvatarName
);
Assert.ok(
await IOUtils.exists(copiedAvatarPath),
"Custom avatar file should be copied to staging"
);
// Create a second profile to recover into
let targetProfile = await createTestProfile({ name: "Target Profile" });
// Ensure target has a standard avatar before recovery
await targetProfile.setAvatar("briefcase");
await updateNotified();
Assert.ok(
!targetProfile.hasCustomAvatar,
"Target should not have custom avatar initially"
);
// Recover into the target profile
let postRecoveryEntry = await resource.recover(
null,
stagingPath,
targetProfile.path
);
Assert.equal(
postRecoveryEntry,
null,
"Should return null as post recovery entry"
);
// Let's refetch the profile to get the most up to date information
targetProfile = await SelectableProfileService.getProfile(targetProfile.id);
// Verify the target profile now has the original profile's data
Assert.equal(
targetProfile.name,
"Custom Avatar Profile",
"Recovered profile name should match original"
);
Assert.ok(
targetProfile.hasCustomAvatar,
"Recovered profile avatar should have a new uuid (and should be custom)"
);
// Verify the custom avatar file was copied to the avatar directory
let avatarDir = PathUtils.join(
ProfilesDatastoreService.constructor.PROFILE_GROUPS_DIR,
"avatars"
);
let recoveredAvatarPath = PathUtils.join(avatarDir, originalAvatarName);
Assert.ok(
await IOUtils.exists(recoveredAvatarPath),
"Custom avatar file should exist in avatar directory"
);
await maybeRemovePath(stagingPath);
sandbox.restore();
});