From 3cc5b9ba0f08a297c34c959a9199f2d6725d7f5e Mon Sep 17 00:00:00 2001 From: Alex Gibson Date: Wed, 30 Aug 2023 14:17:16 +0100 Subject: [PATCH] Pass Traffic Cop custom referrer to attribution scripts (Fixes #13593) --- media/js/base/core-datalayer-page-id.js | 25 +++++++++++++++++ media/js/base/fxa-attribution.es6.js | 12 +++++++- media/js/base/stub-attribution.js | 12 +++++++- media/js/glean/utils.es6.js | 8 +++++- .../unit/spec/base/core-datalayer-page-id.js | 28 ++++++++++++++++++- tests/unit/spec/base/fxa-attribution.js | 18 ++++++++++++ tests/unit/spec/base/stub-attribution.js | 20 +++++++++++++ tests/unit/spec/glean/utils.js | 18 ++++++++++++ 8 files changed, 137 insertions(+), 4 deletions(-) diff --git a/media/js/base/core-datalayer-page-id.js b/media/js/base/core-datalayer-page-id.js index 39077744f48..0b569128000 100644 --- a/media/js/base/core-datalayer-page-id.js +++ b/media/js/base/core-datalayer-page-id.js @@ -15,6 +15,8 @@ if (typeof window.Mozilla === 'undefined') { var dataLayer = (window.dataLayer = window.dataLayer || []); var Analytics = {}; + Analytics.customReferrer = ''; + /** Returns page ID used in Event Category for GA events tracked on page. * @param {String} path - URL path name fallback if page ID does not exist. * @return {String} GTM page ID. @@ -68,11 +70,34 @@ if (typeof window.Mozilla === 'undefined') { // Traffic Cop sets the referrer to 'direct' if document.referer is empty // prior to the redirect, so this value will either be a URL or the string 'direct'. dataObj.customReferrer = referrer; + + // make the custom referrer available to other scripts. + Analytics.customReferrer = referrer; } return dataObj; }; + /** + * Returns custom referrer set by Traffic Cop if exists, + * else returns standard referrer. + * See https://github.com/mozilla/bedrock/issues/13593 + * @returns {String} referrer + */ + Analytics.getReferrer = function (ref) { + var referrer = typeof ref === 'string' ? ref : document.referrer; + var customReferrer = Analytics.customReferrer; + + if (customReferrer) { + // If customReferrer is returned from TC as "direct", + // return an empty string which is the default value + // for document.referrer. Otherwise return customReferrer. + return customReferrer === 'direct' ? '' : customReferrer; + } + + return referrer; + }; + // Push page ID into dataLayer so it's ready when GTM container loads. dataLayer.push(Analytics.buildDataObject()); diff --git a/media/js/base/fxa-attribution.es6.js b/media/js/base/fxa-attribution.es6.js index c5146919253..c4ff8e6505a 100644 --- a/media/js/base/fxa-attribution.es6.js +++ b/media/js/base/fxa-attribution.es6.js @@ -80,8 +80,18 @@ FxaAttribution.getFxALinkReferralData = () => { return null; }; -FxaAttribution.getSearchReferralData = (ref) => { +FxaAttribution.getReferrer = (ref) => { const referrer = typeof ref === 'string' ? ref : document.referrer; + + if (typeof window.Mozilla.Analytics !== 'undefined') { + return Mozilla.Analytics.getReferrer(referrer); + } + + return referrer; +}; + +FxaAttribution.getSearchReferralData = (ref) => { + const referrer = FxaAttribution.getReferrer(ref); const google = /^https?:\/\/www\.google\.\w{2,3}(\.\w{2})?\/?/; const bing = /^https?:\/\/www\.bing\.com\/?/; const yahoo = /^https?:\/\/(\w*\.)?search\.yahoo\.com\/?/; diff --git a/media/js/base/stub-attribution.js b/media/js/base/stub-attribution.js index 779581acc16..171db82f985 100644 --- a/media/js/base/stub-attribution.js +++ b/media/js/base/stub-attribution.js @@ -383,6 +383,16 @@ if (typeof window.Mozilla === 'undefined') { _checkGA(); }; + StubAttribution.getReferrer = function (ref) { + var referrer = typeof ref === 'string' ? ref : document.referrer; + + if (typeof window.Mozilla.Analytics !== 'undefined') { + return Mozilla.Analytics.getReferrer(referrer); + } + + return referrer; + }; + /** * Gets utm parameters and referrer information from the web page if they exist. * @param {String} ref - Optional referrer to facilitate testing. @@ -395,7 +405,7 @@ if (typeof window.Mozilla === 'undefined') { params.get('experiment') || StubAttribution.experimentName; var variation = params.get('variation') || StubAttribution.experimentVariation; - var referrer = typeof ref !== 'undefined' ? ref : document.referrer; + var referrer = StubAttribution.getReferrer(ref); var ua = StubAttribution.getUserAgent(); var clientID = StubAttribution.getGAClientID(); diff --git a/media/js/glean/utils.es6.js b/media/js/glean/utils.es6.js index a78028cb0b9..9808748fdbc 100644 --- a/media/js/glean/utils.es6.js +++ b/media/js/glean/utils.es6.js @@ -40,7 +40,13 @@ const Utils = { }, getReferrer: (ref) => { - return typeof ref === 'string' ? ref : document.referrer; + const referrer = typeof ref === 'string' ? ref : document.referrer; + + if (typeof window.Mozilla.Analytics !== 'undefined') { + return Mozilla.Analytics.getReferrer(referrer); + } + + return referrer; }, getHttpStatus: () => { diff --git a/tests/unit/spec/base/core-datalayer-page-id.js b/tests/unit/spec/base/core-datalayer-page-id.js index dd66acef4e8..f6f182fa492 100644 --- a/tests/unit/spec/base/core-datalayer-page-id.js +++ b/tests/unit/spec/base/core-datalayer-page-id.js @@ -10,6 +10,10 @@ */ describe('core-datalayer-page-id.js', function () { + afterEach(function () { + Mozilla.Analytics.customReferrer = ''; + }); + describe('getPageId', function () { const html = document.documentElement; @@ -52,11 +56,13 @@ describe('core-datalayer-page-id.js', function () { describe('buildDataObject', function () { it('should contain customReferrer if found in cookie', function () { + const expected = 'http://www.google.com'; spyOn(Mozilla.Analytics, 'getTrafficCopReferrer').and.returnValue( - 'http://www.google.com' + expected ); const obj = Mozilla.Analytics.buildDataObject(); expect(obj.customReferrer).toBeDefined(); + expect(Mozilla.Analytics.customReferrer).toEqual(expected); }); it('should not contain customReferrer if not found in cookie', function () { @@ -65,6 +71,26 @@ describe('core-datalayer-page-id.js', function () { ); const obj = Mozilla.Analytics.buildDataObject(); expect(obj.customReferrer).not.toBeDefined(); + expect(Mozilla.Analytics.customReferrer).toEqual(''); + }); + }); + + describe('getReferrer', function () { + it('should return a custom referrer when set', function () { + const expected = 'http://www.google.com'; + Mozilla.Analytics.customReferrer = expected; + expect(Mozilla.Analytics.getReferrer()).toEqual(expected); + }); + + it('should return an empty string if customReferrer is direct', function () { + Mozilla.Analytics.customReferrer = 'direct'; + expect(Mozilla.Analytics.getReferrer()).toEqual(''); + }); + + it('should return standard document referrer otherwise', function () { + const expected = 'http://www.bing.com'; + Mozilla.Analytics.customReferrer = ''; + expect(Mozilla.Analytics.getReferrer(expected)).toEqual(expected); }); }); }); diff --git a/tests/unit/spec/base/fxa-attribution.js b/tests/unit/spec/base/fxa-attribution.js index 172a22f3488..5eca9834875 100644 --- a/tests/unit/spec/base/fxa-attribution.js +++ b/tests/unit/spec/base/fxa-attribution.js @@ -16,6 +16,10 @@ describe('fxa-attribution.js', function () { window.Mozilla.dntEnabled = sinon.stub(); }); + afterEach(function () { + Mozilla.Analytics.customReferrer = ''; + }); + describe('getHostName', function () { it('should return a hostname as expected', function () { const url1 = @@ -538,6 +542,20 @@ describe('fxa-attribution.js', function () { }); }); + describe('getReferrer', function () { + it('should return a custom referrer when set', function () { + const expected = 'http://www.google.com'; + Mozilla.Analytics.customReferrer = expected; + expect(FxaAttribution.getReferrer()).toEqual(expected); + }); + + it('should return standard document referrer otherwise', function () { + const expected = 'http://www.bing.com'; + Mozilla.Analytics.customReferrer = ''; + expect(FxaAttribution.getReferrer(expected)).toEqual(expected); + }); + }); + describe('setFxALinkReferralCookie', function () { it('should set a referral cookie as expected', function () { spyOn(Mozilla, 'dntEnabled').and.returnValue(false); diff --git a/tests/unit/spec/base/stub-attribution.js b/tests/unit/spec/base/stub-attribution.js index 3e3e555241a..af0d4c535e2 100644 --- a/tests/unit/spec/base/stub-attribution.js +++ b/tests/unit/spec/base/stub-attribution.js @@ -24,6 +24,10 @@ describe('stub-attribution.js', function () { window.dataLayer.push = sinon.stub(); }); + afterEach(function () { + Mozilla.Analytics.customReferrer = ''; + }); + describe('init', function () { let data = {}; @@ -536,6 +540,22 @@ describe('stub-attribution.js', function () { }); }); + describe('getReferrer', function () { + it('should return a custom referrer when set', function () { + const expected = 'http://www.google.com'; + Mozilla.Analytics.customReferrer = expected; + expect(Mozilla.StubAttribution.getReferrer()).toEqual(expected); + }); + + it('should return standard document referrer otherwise', function () { + const expected = 'http://www.bing.com'; + Mozilla.Analytics.customReferrer = ''; + expect(Mozilla.StubAttribution.getReferrer(expected)).toEqual( + expected + ); + }); + }); + describe('getAttributionData', function () { beforeEach(function () { // stub out GA client ID diff --git a/tests/unit/spec/glean/utils.js b/tests/unit/spec/glean/utils.js index 5339c70a8b9..0841e01335d 100644 --- a/tests/unit/spec/glean/utils.js +++ b/tests/unit/spec/glean/utils.js @@ -12,6 +12,10 @@ import Utils from '../../../../media/js/glean/utils.es6'; describe('utilsjs', function () { + afterEach(function () { + Mozilla.Analytics.customReferrer = ''; + }); + describe('getPathFromUrl', function () { it('should return the path from a page URL excluding locale', function () { expect(Utils.getPathFromUrl('/en-US/firefox/new/')).toEqual( @@ -80,6 +84,20 @@ describe('utilsjs', function () { }); }); + describe('getReferrer', function () { + it('should return a custom referrer when set', function () { + const expected = 'http://www.google.com'; + Mozilla.Analytics.customReferrer = expected; + expect(Utils.getReferrer()).toEqual(expected); + }); + + it('should return standard document referrer otherwise', function () { + const expected = 'http://www.bing.com'; + Mozilla.Analytics.customReferrer = ''; + expect(Utils.getReferrer(expected)).toEqual(expected); + }); + }); + describe('getHttpStatus', function () { afterEach(function () { document