/* Any copyright is dedicated to the Public Domain. https://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const { sinon } = ChromeUtils.importESModule( "resource://testing-common/Sinon.sys.mjs" ); const execProcess = sinon.stub(); const sendCommandLine = sinon.stub().throws(Cr.NS_ERROR_NOT_AVAILABLE); const commandLineHandler = sinon.stub(); add_setup(async () => { await initSelectableProfileService(); sinon.replace( getSelectableProfileService(), "sendCommandLine", (path, args, raise) => sendCommandLine(path, [...args], raise) ); sinon.replace(getSelectableProfileService(), "execProcess", execProcess); let { nsDefaultCommandLineHandler: browserClh } = ChromeUtils.importESModule( "resource:///modules/BrowserContentHandler.sys.mjs" ); sinon.replace(browserClh.prototype, "handle", commandLineHandler); }); function nextCall(stub) { let { promise, resolve } = Promise.withResolvers(); stub.callsFake(() => resolve()); return promise; } add_task(async function test_profiles_update() { let clh = Cc[ "@mozilla.org/browser/selectable-profiles-service-clh;1" ].createInstance(Ci.nsICommandLineHandler); let observer = sinon.stub(); Services.obs.addObserver(observer, "sps-profiles-updated"); let observerArgsPromise = nextCall(observer); let cmdLine = Cu.createCommandLine( ["--profiles-updated"], null, Ci.nsICommandLine.STATE_REMOTE_AUTO ); clh.handle(cmdLine); await observerArgsPromise; Assert.equal(observer.callCount, 1, "Should have called the observer"); Assert.deepEqual(observer.firstCall.args, [ null, "sps-profiles-updated", "remote", ]); Assert.ok( cmdLine.preventDefault, "Should have prevented the default handler" ); Services.obs.removeObserver(observer, "sps-profiles-updated"); }); add_task(async function test_redirect_args() { if (Services.appinfo.OS !== "Darwin") { // This behaviour is specific to macOS return; } let clh = Cc[ "@mozilla.org/browser/selectable-profiles-service-clh;1" ].createInstance(Ci.nsICommandLineHandler); let { rootDir } = getProfileService().currentProfile; let profilePath = rootDir.path; let cmdLine = Cu.createCommandLine( ["-url", "https://www.google.com/"], null, Ci.nsICommandLine.STATE_REMOTE_EXPLICIT ); clh.handle(cmdLine); Assert.ok( cmdLine.preventDefault, "Should have prevented the default handler" ); await nextCall(commandLineHandler); Assert.equal( commandLineHandler.callCount, 1, "Should have called the main browser command line handler directly" ); let [generatedCmdLine] = commandLineHandler.firstCall.args; Assert.equal( generatedCmdLine.length, 2, "Should have generated a command line with the correct number of arguments" ); Assert.equal(generatedCmdLine.getArgument(0), "-url"); Assert.equal( generatedCmdLine.getArgument(1), "https://www.google.com/", "Should have generated a command line with the correct URL" ); commandLineHandler.resetHistory(); let profileData = readProfilesIni(); for (let profile of profileData.profiles) { if (profile.storeID == getSelectableProfileService().storeID) { profile.path = profile.path.replace(rootDir.leafName, "other-profile"); break; } } writeProfilesIni(profileData); rootDir.leafName = "other-profile"; profilePath = rootDir.path; cmdLine = Cu.createCommandLine( ["-url", "https://www.example.com/", "-url", "https://www.mozilla.org/"], null, Ci.nsICommandLine.STATE_REMOTE_EXPLICIT ); clh.handle(cmdLine); Assert.ok( cmdLine.preventDefault, "Should have prevented the default handler" ); await nextCall(execProcess); Assert.equal( sendCommandLine.callCount, 1, "Should have attempted to remote once" ); Assert.deepEqual( sendCommandLine.firstCall.args, [ profilePath, ["-url", "https://www.example.com/", "-url", "https://www.mozilla.org/"], true, ], "should have used the right arguments" ); sendCommandLine.resetHistory(); Assert.equal(execProcess.callCount, 1, "Should have attempted to exec once"); Assert.deepEqual( execProcess.firstCall.args, [ [ "-foreground", "-url", "https://www.example.com/", "-url", "https://www.mozilla.org/", ], ], "should have used the right arguments" ); execProcess.resetHistory(); });