diff options
Diffstat (limited to 'toolkit/components/normandy/lib/ClientEnvironment.sys.mjs')
-rw-r--r-- | toolkit/components/normandy/lib/ClientEnvironment.sys.mjs | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/toolkit/components/normandy/lib/ClientEnvironment.sys.mjs b/toolkit/components/normandy/lib/ClientEnvironment.sys.mjs new file mode 100644 index 0000000000..16645dd3b2 --- /dev/null +++ b/toolkit/components/normandy/lib/ClientEnvironment.sys.mjs @@ -0,0 +1,123 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { ClientEnvironmentBase } from "resource://gre/modules/components-utils/ClientEnvironment.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + AddonRollouts: "resource://normandy/lib/AddonRollouts.sys.mjs", + AddonStudies: "resource://normandy/lib/AddonStudies.sys.mjs", + NormandyApi: "resource://normandy/lib/NormandyApi.sys.mjs", + PreferenceExperiments: + "resource://normandy/lib/PreferenceExperiments.sys.mjs", + PreferenceRollouts: "resource://normandy/lib/PreferenceRollouts.sys.mjs", +}); + +// Cached API request for client attributes that are determined by the Normandy +// service. +let _classifyRequest = null; + +export class ClientEnvironment extends ClientEnvironmentBase { + /** + * Fetches information about the client that is calculated on the server, + * like geolocation and the current time. + * + * The server request is made lazily and is cached for the entire browser + * session. + */ + static async getClientClassification() { + if (!_classifyRequest) { + _classifyRequest = lazy.NormandyApi.classifyClient(); + } + return _classifyRequest; + } + + static clearClassifyCache() { + _classifyRequest = null; + } + + /** + * Test wrapper that mocks the server request for classifying the client. + * @param {Object} data Fake server data to use + * @param {Function} testFunction Test function to execute while mock data is in effect. + */ + static withMockClassify(data, testFunction) { + return async function inner() { + const oldRequest = _classifyRequest; + _classifyRequest = Promise.resolve(data); + await testFunction(); + _classifyRequest = oldRequest; + }; + } + + static get userId() { + return ClientEnvironment.randomizationId; + } + + static get country() { + return (async () => { + const { country } = await ClientEnvironment.getClientClassification(); + return country; + })(); + } + + static get request_time() { + return (async () => { + const { request_time } = + await ClientEnvironment.getClientClassification(); + return request_time; + })(); + } + + static get experiments() { + return (async () => { + const names = { all: [], active: [], expired: [] }; + + for (const { + slug, + expired, + } of await lazy.PreferenceExperiments.getAll()) { + names.all.push(slug); + if (expired) { + names.expired.push(slug); + } else { + names.active.push(slug); + } + } + + return names; + })(); + } + + static get studies() { + return (async () => { + const rv = { pref: {}, addon: {} }; + for (const prefStudy of await lazy.PreferenceExperiments.getAll()) { + rv.pref[prefStudy.slug] = prefStudy; + } + for (const addonStudy of await lazy.AddonStudies.getAll()) { + rv.addon[addonStudy.slug] = addonStudy; + } + return rv; + })(); + } + + static get rollouts() { + return (async () => { + const rv = { pref: {}, addon: {} }; + for (const prefRollout of await lazy.PreferenceRollouts.getAll()) { + rv.pref[prefRollout.slug] = prefRollout; + } + for (const addonRollout of await lazy.AddonRollouts.getAll()) { + rv.addon[addonRollout.slug] = addonRollout; + } + return rv; + })(); + } + + static get isFirstRun() { + return Services.prefs.getBoolPref("app.normandy.first_run", true); + } +} |