From 744c62ad8fd57d199aac422811cafc40e20c5153 Mon Sep 17 00:00:00 2001 From: Andrei Oprea Date: Mon, 7 Jun 2021 10:12:55 +0000 Subject: [PATCH] Bug 1714449 - Feature API does not fire update event on startup r=k88hudson Differential Revision: https://phabricator.services.mozilla.com/D116777 --- .../components/nimbus/lib/ExperimentStore.jsm | 10 +++++++ .../test_ExperimentAPI_ExperimentFeature.js | 30 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/toolkit/components/nimbus/lib/ExperimentStore.jsm b/toolkit/components/nimbus/lib/ExperimentStore.jsm index 8ea8e4647eae63..9550352e4cbb72 100644 --- a/toolkit/components/nimbus/lib/ExperimentStore.jsm +++ b/toolkit/components/nimbus/lib/ExperimentStore.jsm @@ -98,6 +98,16 @@ class ExperimentStore extends SharedDataMap { super(sharedDataKey || DEFAULT_STORE_ID, options); } + async init() { + await super.init(); + + this.getAllActive().forEach(experiment => { + experiment.featureIds?.forEach(feature => + this._emitFeatureUpdate(feature, "feature-experiment-loaded") + ); + }); + } + /** * Given a feature identifier, find an active experiment that matches that feature identifier. * This assumes, for now, that there is only one active experiment per feature per browser. diff --git a/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature.js b/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature.js index 8586b84be0f374..8befb1a3cf00e3 100644 --- a/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature.js +++ b/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature.js @@ -523,3 +523,33 @@ add_task(async function test_isEnabled_backwards_compatible() { ); Assert.ok(exposureSpy.calledOnce, "Exposure event sent"); }); + +add_task(async function test_onUpdate_before_store_ready() { + let sandbox = sinon.createSandbox(); + const feature = new ExperimentFeature("foo", FAKE_FEATURE_MANIFEST); + const stub = sandbox.stub(); + const manager = ExperimentFakes.manager(); + sandbox.stub(ExperimentAPI, "_store").get(() => manager.store); + sandbox.stub(manager.store, "getAllActive").returns([ + ExperimentFakes.experiment("foo-experiment", { + featureIds: ["foo"], + branch: { slug: "control", feature: { featureId: "foo", value: null } }, + }), + ]); + + // We register for updates before the store finished loading experiments + // from disk + feature.onUpdate(stub); + + await manager.onStartup(); + + Assert.ok( + stub.calledOnce, + "Called on startup after loading experiments from disk" + ); + Assert.equal( + stub.firstCall.args[1], + "feature-experiment-loaded", + "Called for the expected reason" + ); +});