/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /** * Tests that if the migrator does not have the permission to * read from the Chrome data directory, that it can request * permission to read from it, if the system allows. */ const { ChromeMigrationUtils } = ChromeUtils.importESModule( "resource:///modules/ChromeMigrationUtils.sys.mjs" ); const { ChromeProfileMigrator } = ChromeUtils.importESModule( "resource:///modules/ChromeProfileMigrator.sys.mjs" ); const { sinon } = ChromeUtils.importESModule( "resource://testing-common/Sinon.sys.mjs" ); const { MockFilePicker } = ChromeUtils.importESModule( "resource://testing-common/MockFilePicker.sys.mjs" ); let gTempDir; add_setup(async () => { Services.prefs.setBoolPref( "browser.migrate.chrome.get_permissions.enabled", true ); gTempDir = do_get_tempdir(); await IOUtils.writeJSON(PathUtils.join(gTempDir.path, "Local State"), []); MockFilePicker.init(/* mock BrowsingContext */ { window: globalThis }); registerCleanupFunction(() => { MockFilePicker.cleanup(); }); }); /** * Tests that canGetPermissions will return false if the platform does * not allow for folder selection in the native file picker, and returns * the data path otherwise. */ add_task(async function test_canGetPermissions() { let sandbox = sinon.createSandbox(); registerCleanupFunction(() => { sandbox.restore(); }); let migrator = new ChromeProfileMigrator(); let canGetPermissionsStub = sandbox .stub(MigrationUtils, "canGetPermissionsOnPlatform") .resolves(false); sandbox.stub(ChromeMigrationUtils, "getDataPath").resolves(gTempDir.path); Assert.ok( !(await migrator.canGetPermissions()), "Should not be able to get permissions." ); canGetPermissionsStub.resolves(true); Assert.equal( await migrator.canGetPermissions(), gTempDir.path, "Should be able to get the permissions path." ); sandbox.restore(); }); /** * Tests that getPermissions will show the native file picker in a * loop until either the user cancels or selects a folder that grants * read permissions to the data directory. */ add_task(async function test_getPermissions() { let sandbox = sinon.createSandbox(); registerCleanupFunction(() => { sandbox.restore(); }); let migrator = new ChromeProfileMigrator(); sandbox.stub(MigrationUtils, "canGetPermissionsOnPlatform").resolves(true); sandbox.stub(ChromeMigrationUtils, "getDataPath").resolves(gTempDir.path); let hasPermissionsStub = sandbox .stub(migrator, "hasPermissions") .resolves(false); Assert.equal( await migrator.canGetPermissions(), gTempDir.path, "Should be able to get the permissions path." ); let filePickerSeenCount = 0; let filePickerShownPromise = new Promise(resolve => { MockFilePicker.showCallback = () => { Assert.ok(true, "Filepicker shown."); MockFilePicker.useDirectory([gTempDir.path]); filePickerSeenCount++; if (filePickerSeenCount > 3) { Assert.ok(true, "File picker looped 3 times."); hasPermissionsStub.resolves(true); resolve(); } }; }); MockFilePicker.returnValue = MockFilePicker.returnOK; Assert.ok( await migrator.getPermissions(), "Should report that we got permissions." ); await filePickerShownPromise; // Make sure that the user can also hit "cancel" and that we // file picker loop. hasPermissionsStub.resolves(false); filePickerSeenCount = 0; filePickerShownPromise = new Promise(resolve => { MockFilePicker.showCallback = () => { Assert.ok(true, "Filepicker shown."); filePickerSeenCount++; Assert.equal(filePickerSeenCount, 1, "Saw the picker once."); resolve(); }; }); MockFilePicker.returnValue = MockFilePicker.returnCancel; Assert.ok( !(await migrator.getPermissions()), "Should report that we didn't get permissions." ); await filePickerShownPromise; sandbox.restore(); }); /** * Tests that if the native file picker chooses a different directory * than the one we originally asked for, that we remap attempts to * read profiles from that new directory. This is because Ubuntu Snaps * will return us paths from the native file picker that are symlinks * to the original directories. */ add_task(async function test_remapDirectories() { let remapDir = new FileUtils.File( await IOUtils.createUniqueDirectory( PathUtils.tempDir, "test-chrome-migration" ) ); let localStatePath = PathUtils.join(remapDir.path, "Local State"); await IOUtils.writeJSON(localStatePath, []); let sandbox = sinon.createSandbox(); registerCleanupFunction(() => { sandbox.restore(); }); let migrator = new ChromeProfileMigrator(); sandbox.stub(MigrationUtils, "canGetPermissionsOnPlatform").resolves(true); sandbox.stub(ChromeMigrationUtils, "getDataPath").resolves(gTempDir.path); let hasPermissionsStub = sandbox .stub(migrator, "hasPermissions") .resolves(false); Assert.equal( await migrator.canGetPermissions(), gTempDir.path, "Should be able to get the permissions path." ); let filePickerShownPromise = new Promise(resolve => { MockFilePicker.showCallback = () => { Assert.ok(true, "Filepicker shown."); MockFilePicker.useDirectory([remapDir.path]); hasPermissionsStub.resolves(true); resolve(); }; }); MockFilePicker.returnValue = MockFilePicker.returnOK; Assert.ok( await migrator.getPermissions(), "Should report that we got permissions." ); Assert.equal( PathUtils.normalize(await migrator.canGetPermissions()), PathUtils.normalize(remapDir.path), "Should be able to get the remapped permissions path." ); await filePickerShownPromise; sandbox.restore(); });