Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion media/js/base/stub-attribution/stub-attribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ if (typeof window.Mozilla === 'undefined') {
? null
: StubAttribution.getGtagClientID();

var campaignForce = document.documentElement.getAttribute(
'data-stub-attribution-campaign-force'
);
var campaignOverride = document.documentElement.getAttribute(
'data-stub-attribution-campaign-override'
);
Expand All @@ -529,7 +532,10 @@ if (typeof window.Mozilla === 'undefined') {
);
var utmCampaign;

if (campaignOverride !== null) {
if (campaignForce !== null) {
// Force always wins and clears existing cookie
utmCampaign = campaignForce;
} else if (campaignOverride !== null) {
// Explicit override via data attribute
utmCampaign = campaignOverride;
} else if (
Expand Down Expand Up @@ -694,6 +700,19 @@ if (typeof window.Mozilla === 'undefined') {
StubAttribution.timeoutCallback = timeoutCallback;
}

/**
* If the page forces a campaign value, invalidate any
* existing cookie so the forced value is picked up.
*/
if (
StubAttribution.hasCookie() &&
document.documentElement.getAttribute(
'data-stub-attribution-campaign-force'
)
) {
StubAttribution.removeCookie();
}

/**
* If cookie already exists, update download links on the page,
* else make a request to the service if within attribution rate.
Expand Down
127 changes: 127 additions & 0 deletions tests/unit/spec/base/stub-attribution/stub-attribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,50 @@ describe('stub-attribution.js', function () {
).toHaveBeenCalledWith(cookieData);
});

it('should invalidate cookie and re-request when data-stub-attribution-campaign-force is set', function () {
const html = document.documentElement;
html.setAttribute(
'data-stub-attribution-campaign-force',
'forced_campaign'
);

spyOn(
Mozilla.StubAttribution,
'withinAttributionRate'
).and.returnValue(true);
spyOn(Mozilla.StubAttribution, 'meetsRequirements').and.returnValue(
true
);
spyOn(Mozilla.StubAttribution, 'hasValidData').and.returnValue(
true
);
spyOn(Mozilla.StubAttribution, 'hasCookie').and.returnValues(
true,
false
);
spyOn(Mozilla.StubAttribution, 'removeCookie');
spyOn(
Mozilla.StubAttribution,
'isFirefoxDownloadThanks'
).and.returnValue(false);
spyOn(
Mozilla.StubAttribution,
'getAttributionData'
).and.returnValue(data);

Mozilla.StubAttribution.init();

expect(Mozilla.StubAttribution.removeCookie).toHaveBeenCalled();
expect(
Mozilla.StubAttribution.checkDataAndRequestAuth
).toHaveBeenCalled();
expect(
Mozilla.StubAttribution.updateBouncerLinks
).not.toHaveBeenCalled();

html.removeAttribute('data-stub-attribution-campaign-force');
});

it('should authenticate attribution data if no session cookie exists', function () {
spyOn(
Mozilla.StubAttribution,
Expand Down Expand Up @@ -782,6 +826,12 @@ describe('stub-attribution.js', function () {
document.documentElement.removeAttribute(
'data-stub-attribution-campaign'
);
document.documentElement.removeAttribute(
'data-stub-attribution-campaign-override'
);
document.documentElement.removeAttribute(
'data-stub-attribution-campaign-force'
);
});

it('should use data-stub-attribution-campaign as fallback when utm_campaign is not in URL params', function () {
Expand Down Expand Up @@ -968,6 +1018,83 @@ describe('stub-attribution.js', function () {
html.removeAttribute('data-stub-attribution-campaign');
});

it('should use data-stub-attribution-campaign-force over utm_campaign from URL params', function () {
const html = document.documentElement;
html.setAttribute(
'data-stub-attribution-campaign-force',
'forced_campaign'
);

const referrer = '';

const utms = {
utm_source: 'desktop-snippet',
utm_medium: 'referral',
utm_campaign: 'F100_4242_otherstuff_in_here',
utm_content: 'rel-esr'
};

const data = {
utm_source: 'desktop-snippet',
utm_medium: 'referral',
utm_campaign: 'forced_campaign',
utm_content: 'rel-esr',
referrer: '',
ua: 'chrome',
client_id_ga4: GA4_CLIENT_ID,
session_id: jasmine.any(String),
dlsource: DLSOURCE
};

spyOn(window._SearchParams.prototype, 'utmParams').and.returnValue(
utms
);
spyOn(Mozilla.StubAttribution, 'getUserAgent').and.returnValue(
'chrome'
);
const result = Mozilla.StubAttribution.getAttributionData(referrer);
expect(result).toEqual(data);
});

it('should use data-stub-attribution-campaign-force over data-stub-attribution-campaign-override', function () {
const html = document.documentElement;
html.setAttribute(
'data-stub-attribution-campaign-force',
'forced_campaign'
);
html.setAttribute(
'data-stub-attribution-campaign-override',
'override_campaign'
);

const referrer = '';

const utms = {
utm_source: undefined,
utm_medium: undefined,
utm_campaign: undefined,
utm_content: undefined
};

const data = {
utm_campaign: 'forced_campaign',
referrer: '',
ua: 'chrome',
client_id_ga4: GA4_CLIENT_ID,
session_id: jasmine.any(String),
dlsource: DLSOURCE
};

spyOn(window._SearchParams.prototype, 'utmParams').and.returnValue(
utms
);
spyOn(Mozilla.StubAttribution, 'getUserAgent').and.returnValue(
'chrome'
);
const result = Mozilla.StubAttribution.getAttributionData(referrer);
expect(result).toEqual(data);
});

it('should not include campaign when neither URL param nor data attribute is set', function () {
const referrer = '';

Expand Down
Loading