tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit e2afb0c982dae5a77f6c7025a626bf57e0b68c3d
parent 5622001e5bf0f47823188963bfcd2b82e4d6cf4b
Author: Rolf Rando <rrando@mozilla.com>
Date:   Wed, 10 Dec 2025 18:55:23 +0000

Bug 2005108 - fix logic bug on randomization r=home-newtab-reviewers,nbarrett

Differential Revision: https://phabricator.services.mozilla.com/D275715

Diffstat:
Mbrowser/extensions/newtab/lib/NewTabContentPing.sys.mjs | 3++-
Mbrowser/extensions/newtab/lib/TelemetryFeed.sys.mjs | 8++++++--
Mbrowser/extensions/newtab/test/xpcshell/test_TelemetryFeed.js | 39+++++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/browser/extensions/newtab/lib/NewTabContentPing.sys.mjs b/browser/extensions/newtab/lib/NewTabContentPing.sys.mjs @@ -350,7 +350,8 @@ export class NewTabContentPing { * Returns true or false with a certain proability specified * * @param {number} prob Probability - * @returns {boolean} Random boolean result of probability prob + * @returns {boolean} Random boolean result of probability prob. A higher prob + * increases the chance of true being returned. */ static decideWithProbability(prob) { if (prob <= 0) { diff --git a/browser/extensions/newtab/lib/TelemetryFeed.sys.mjs b/browser/extensions/newtab/lib/TelemetryFeed.sys.mjs @@ -883,7 +883,7 @@ export class TelemetryFeed { const { p } = this._privateRandomContentTelemetryProbablityValues[cache_key]; - if (!lazy.NewTabContentPing.decideWithProbability(p)) { + if (lazy.NewTabContentPing.decideWithProbability(p)) { return item; } const allRecs = this.getAllRecommendations(); // Number of recommendations has changed @@ -905,7 +905,11 @@ export class TelemetryFeed { }; // If we're replacing a non top stories item, then assign the appropriate // section to the item - if (resultItem.section !== TOP_STORIES_SECTION_NAME && randomItem.section) { + if ( + resultItem.section && + resultItem.section !== TOP_STORIES_SECTION_NAME && + randomItem.section + ) { resultItem.section = randomItem.section; resultItem.section_position = randomItem.section_position; } diff --git a/browser/extensions/newtab/test/xpcshell/test_TelemetryFeed.js b/browser/extensions/newtab/test/xpcshell/test_TelemetryFeed.js @@ -17,6 +17,7 @@ ChromeUtils.defineESModuleGetters(this, { HomePage: "resource:///modules/HomePage.sys.mjs", JsonSchemaValidator: "resource://gre/modules/components-utils/JsonSchemaValidator.sys.mjs", + NewTabContentPing: "resource://newtab/lib/NewTabContentPing.sys.mjs", sinon: "resource://testing-common/Sinon.sys.mjs", TelemetryController: "resource://gre/modules/TelemetryController.sys.mjs", TelemetryFeed: "resource://newtab/lib/TelemetryFeed.sys.mjs", @@ -2711,3 +2712,41 @@ add_task(async function test_handleBlockUrl_no_record_dismiss_on_no_session() { sandbox.restore(); }); + +add_task(function test_randomizeOrganicContentEvent() { + info( + "TelemetryFeed._randomizeOrganicContentEvent should return true or false" + + " based on the given probability" + ); + let sandbox = sinon.createSandbox(); + let instance = new TelemetryFeed(); + + const computeRec = id => ({ + corpus_item_id: `item-${id}`, + topic: "a", + is_sponsored: false, + section_id: "section", + section_position: 3, + }); + const allRecs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(computeRec); + sandbox.stub(instance, "getRecommendationCount").returns(allRecs.length); + sandbox.stub(instance, "getAllRecommendations").returns(allRecs); + instance._privateRandomContentTelemetryProbablityValues = { epsilon: 30 }; + let decideStub = sandbox.stub(NewTabContentPing, "decideWithProbability"); + decideStub.returns(true); + let result = instance.randomizeOrganicContentEvent(allRecs[0]); + Assert.equal(result, allRecs[0]); + Assert.ok(decideStub.calledOnce, "decideWithProbability was called once"); + const [probUsed] = decideStub.firstCall.args; + Assert.greater(probUsed, 0.9); // Epsilon 30 is very high probability + Assert.less(probUsed, 1.01); + + // Run again - randomization kicks in + decideStub.returns(false); + sandbox.stub(NewTabContentPing, "secureRandIntInRange").returns(3); + result = instance.randomizeOrganicContentEvent(allRecs[0]); + Assert.equal(probUsed, decideStub.lastCall.args[0]); + Assert.deepEqual(result, allRecs[3]); + + sandbox.restore(); +});