summaryrefslogtreecommitdiffstats
path: root/browser/components/backup/tests/xpcshell/test_MiscDataBackupResource.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/backup/tests/xpcshell/test_MiscDataBackupResource.js')
-rw-r--r--browser/components/backup/tests/xpcshell/test_MiscDataBackupResource.js203
1 files changed, 196 insertions, 7 deletions
diff --git a/browser/components/backup/tests/xpcshell/test_MiscDataBackupResource.js b/browser/components/backup/tests/xpcshell/test_MiscDataBackupResource.js
index e57dd50cd3..ab63b65332 100644
--- a/browser/components/backup/tests/xpcshell/test_MiscDataBackupResource.js
+++ b/browser/components/backup/tests/xpcshell/test_MiscDataBackupResource.js
@@ -7,20 +7,27 @@ const { MiscDataBackupResource } = ChromeUtils.importESModule(
"resource:///modules/backup/MiscDataBackupResource.sys.mjs"
);
+const { ActivityStreamStorage } = ChromeUtils.importESModule(
+ "resource://activity-stream/lib/ActivityStreamStorage.sys.mjs"
+);
+
+const { ProfileAge } = ChromeUtils.importESModule(
+ "resource://gre/modules/ProfileAge.sys.mjs"
+);
+
/**
* Tests that we can measure miscellaneous files in the profile directory.
*/
add_task(async function test_measure() {
Services.fog.testResetFOG();
- const EXPECTED_MISC_KILOBYTES_SIZE = 241;
+ const EXPECTED_MISC_KILOBYTES_SIZE = 231;
const tempDir = await IOUtils.createUniqueDirectory(
PathUtils.tempDir,
"MiscDataBackupResource-measurement-test"
);
const mockFiles = [
- { path: "times.json", sizeInKB: 5 },
{ path: "enumerate_devices.txt", sizeInKB: 1 },
{ path: "protections.sqlite", sizeInKB: 100 },
{ path: "SiteSecurityServiceState.bin", sizeInKB: 10 },
@@ -69,12 +76,16 @@ add_task(async function test_backup() {
);
const simpleCopyFiles = [
- { path: "times.json" },
{ path: "enumerate_devices.txt" },
{ path: "SiteSecurityServiceState.bin" },
];
await createTestFiles(sourcePath, simpleCopyFiles);
+ // Create our fake database files. We don't expect this to be copied to the
+ // staging directory in this test due to our stubbing of the backup method, so
+ // we don't include it in `simpleCopyFiles`.
+ await createTestFiles(sourcePath, [{ path: "protections.sqlite" }]);
+
// We have no need to test that Sqlite.sys.mjs's backup method is working -
// this is something that is tested in Sqlite's own tests. We can just make
// sure that it's being called using sinon. Unfortunately, we cannot do the
@@ -85,7 +96,27 @@ add_task(async function test_backup() {
};
sandbox.stub(Sqlite, "openConnection").returns(fakeConnection);
- await miscDataBackupResource.backup(stagingPath, sourcePath);
+ let snippetsTableStub = {
+ getAllKeys: sandbox.stub().resolves(["key1", "key2"]),
+ get: sandbox.stub().callsFake(key => {
+ return { key: `value for ${key}` };
+ }),
+ };
+
+ sandbox
+ .stub(ActivityStreamStorage.prototype, "getDbTable")
+ .withArgs("snippets")
+ .resolves(snippetsTableStub);
+
+ let manifestEntry = await miscDataBackupResource.backup(
+ stagingPath,
+ sourcePath
+ );
+ Assert.equal(
+ manifestEntry,
+ null,
+ "MiscDataBackupResource.backup should return null as its ManifestEntry"
+ );
await assertFilesExist(stagingPath, simpleCopyFiles);
@@ -102,12 +133,170 @@ add_task(async function test_backup() {
"Called backup on the protections.sqlite Sqlite connection"
);
- // Bug 1890585 - we don't currently have the ability to copy the
- // chrome-privileged IndexedDB databases under storage/permanent/chrome, so
- // we'll just skip testing that for now.
+ // Bug 1890585 - we don't currently have the generalized ability to copy the
+ // chrome-privileged IndexedDB databases under storage/permanent/chrome, but
+ // we do support copying individual IndexedDB databases by manually exporting
+ // and re-importing their contents.
+ let snippetsBackupPath = PathUtils.join(
+ stagingPath,
+ "activity-stream-snippets.json"
+ );
+ Assert.ok(
+ await IOUtils.exists(snippetsBackupPath),
+ "The activity-stream-snippets.json file should exist"
+ );
+ let snippetsBackupContents = await IOUtils.readJSON(snippetsBackupPath);
+ Assert.deepEqual(
+ snippetsBackupContents,
+ {
+ key1: { key: "value for key1" },
+ key2: { key: "value for key2" },
+ },
+ "The contents of the activity-stream-snippets.json file should be as expected"
+ );
await maybeRemovePath(stagingPath);
await maybeRemovePath(sourcePath);
sandbox.restore();
});
+
+/**
+ * Test that the recover method correctly copies items from the recovery
+ * directory into the destination profile directory.
+ */
+add_task(async function test_recover() {
+ let miscBackupResource = new MiscDataBackupResource();
+ let recoveryPath = await IOUtils.createUniqueDirectory(
+ PathUtils.tempDir,
+ "MiscDataBackupResource-recovery-test"
+ );
+ let destProfilePath = await IOUtils.createUniqueDirectory(
+ PathUtils.tempDir,
+ "MiscDataBackupResource-test-profile"
+ );
+
+ // Write a dummy times.json into the xpcshell test profile directory. We
+ // expect it to be copied into the destination profile.
+ let originalProfileAge = await ProfileAge(PathUtils.profileDir);
+ await originalProfileAge.computeAndPersistCreated();
+ Assert.ok(
+ await IOUtils.exists(PathUtils.join(PathUtils.profileDir, "times.json"))
+ );
+
+ const simpleCopyFiles = [
+ { path: "enumerate_devices.txt" },
+ { path: "protections.sqlite" },
+ { path: "SiteSecurityServiceState.bin" },
+ ];
+ await createTestFiles(recoveryPath, simpleCopyFiles);
+
+ const SNIPPETS_BACKUP_FILE = "activity-stream-snippets.json";
+
+ // We'll also separately create the activity-stream-snippets.json file, which
+ // is not expected to be copied into the profile directory, but is expected
+ // to exist in the recovery path.
+ await createTestFiles(recoveryPath, [{ path: SNIPPETS_BACKUP_FILE }]);
+
+ // The backup method is expected to have returned a null ManifestEntry
+ let postRecoveryEntry = await miscBackupResource.recover(
+ null /* manifestEntry */,
+ recoveryPath,
+ destProfilePath
+ );
+ Assert.deepEqual(
+ postRecoveryEntry,
+ {
+ snippetsBackupFile: PathUtils.join(recoveryPath, SNIPPETS_BACKUP_FILE),
+ },
+ "MiscDataBackupResource.recover should return the snippets backup data " +
+ "path as its post recovery entry"
+ );
+
+ await assertFilesExist(destProfilePath, simpleCopyFiles);
+
+ // The activity-stream-snippets.json path should _not_ have been written to
+ // the profile path.
+ Assert.ok(
+ !(await IOUtils.exists(
+ PathUtils.join(destProfilePath, SNIPPETS_BACKUP_FILE)
+ )),
+ "Snippets backup data should not have gone into the profile directory"
+ );
+
+ // The times.json file should have been copied over and a backup recovery
+ // time written into it.
+ Assert.ok(
+ await IOUtils.exists(PathUtils.join(destProfilePath, "times.json"))
+ );
+ let copiedProfileAge = await ProfileAge(destProfilePath);
+ Assert.equal(
+ await originalProfileAge.created,
+ await copiedProfileAge.created,
+ "Created timestamp should match."
+ );
+ Assert.equal(
+ await originalProfileAge.firstUse,
+ await copiedProfileAge.firstUse,
+ "First use timestamp should match."
+ );
+ Assert.ok(
+ await copiedProfileAge.recoveredFromBackup,
+ "Backup recovery timestamp should have been set."
+ );
+
+ await maybeRemovePath(recoveryPath);
+ await maybeRemovePath(destProfilePath);
+});
+
+/**
+ * Test that the postRecovery method correctly writes the snippets backup data
+ * into the snippets IndexedDB table.
+ */
+add_task(async function test_postRecovery() {
+ let sandbox = sinon.createSandbox();
+
+ let fakeProfilePath = await IOUtils.createUniqueDirectory(
+ PathUtils.tempDir,
+ "MiscDataBackupResource-test-profile"
+ );
+ let fakeSnippetsData = {
+ key1: "value1",
+ key2: "value2",
+ };
+ const SNIPPEST_BACKUP_FILE = PathUtils.join(
+ fakeProfilePath,
+ "activity-stream-snippets.json"
+ );
+
+ await IOUtils.writeJSON(SNIPPEST_BACKUP_FILE, fakeSnippetsData);
+
+ let snippetsTableStub = {
+ set: sandbox.stub(),
+ };
+
+ sandbox
+ .stub(ActivityStreamStorage.prototype, "getDbTable")
+ .withArgs("snippets")
+ .resolves(snippetsTableStub);
+
+ let miscBackupResource = new MiscDataBackupResource();
+ await miscBackupResource.postRecovery({
+ snippetsBackupFile: SNIPPEST_BACKUP_FILE,
+ });
+
+ Assert.ok(
+ snippetsTableStub.set.calledTwice,
+ "The snippets table's set method was called twice"
+ );
+ Assert.ok(
+ snippetsTableStub.set.firstCall.calledWith("key1", "value1"),
+ "The snippets table's set method was called with the first key-value pair"
+ );
+ Assert.ok(
+ snippetsTableStub.set.secondCall.calledWith("key2", "value2"),
+ "The snippets table's set method was called with the second key-value pair"
+ );
+
+ sandbox.restore();
+});