Skip to content

Commit

Permalink
Add custom functions to create close cookies
Browse files Browse the repository at this point in the history
Calling `mw.centralNotice.hideBanner()` causes a spike in false
tracking events during the fundraising campaign, due to the
function looping the multiple URLS contained in `wgNoticeHideUrls`
in order to set cookies on multiple wikis.

This replaces the `hideBanner` call with custom setters that only
create the cookies on wikipedia.org.

See https://phabricator.wikimedia.org/T344381
  • Loading branch information
Abban committed Aug 28, 2023
1 parent c85306e commit 353ddda
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/page/MediaWiki/WindowMediaWiki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { MediaWiki } from '@src/page/MediaWiki/MediaWiki';
import { LegacyBannerEvent } from '@src/page/MediaWiki/LegacyBannerEvent';
import { SizeIssue } from '@src/page/MediaWiki/SizeIssue';
import { BannerEvent } from '@src/page/MediaWiki/BannerEvent';
import { setCookie } from '@src/page/MediaWiki/setCookie';
import { createImageCookieSetter } from '@src/page/MediaWiki/createImageCookieSetter';

interface MediaWikiTools {
config: { get: ( item: string ) => any };
Expand Down Expand Up @@ -52,16 +54,21 @@ export class WindowMediaWiki implements MediaWiki {
}

public preventBannerDisplayForPeriod(): void {
window.mw.centralNotice.hideBanner();
this.hideBanner( 'close', this.getConfigItem( 'wgNoticeCookieDurations' ).close );
}

public preventBannerDisplayUntilEndOfCampaign(): void {
const endOfYear = new Date( new Date().getFullYear(), 11, 31, 23, 59, 59 );
const secondsToEndOfYear = Math.abs( ( endOfYear.getTime() - Date.now() ) / 1000 );
window.mw.centralNotice.customHideBanner( 'donate', secondsToEndOfYear );
this.hideBanner( 'donate', secondsToEndOfYear );
}

public setBannerLoadedButHidden(): void {
window.mw.centralNotice.setBannerLoadedButHidden();
}

private hideBanner( reason: string, durationInSeconds: number ): void {
setCookie( reason, new Date(), durationInSeconds );
createImageCookieSetter( reason, durationInSeconds, this.getConfigItem( 'wgNoticeHideUrls' )[ 0 ] );
}
}
19 changes: 19 additions & 0 deletions src/page/MediaWiki/createImageCookieSetter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const HIDE_EVENT_TRACKING_CATEGORY = 'fundraising';

export function createImageCookieSetter( reason: string, durationInSeconds: number, trackingUrl: string ): void {
const trackingData = {
duration: String( durationInSeconds ),
category: HIDE_EVENT_TRACKING_CATEGORY,
reason: reason
};

const baseUrl = new URL( 'https:' + trackingUrl );
const newParams = new URLSearchParams( [
...Array.from( baseUrl.searchParams.entries() ),
...Object.entries( trackingData )
] ).toString();

const trackingImgUrl = new URL( `${ baseUrl.origin }${ baseUrl.pathname }?${ newParams }` );

document.createElement( 'img' ).src = trackingImgUrl.toString();
}
14 changes: 14 additions & 0 deletions src/page/MediaWiki/setCookie.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const COOKIE_NAME = 'centralnotice_hide_fundraising';

export function setCookie( reason: string, created: Date, durationInSeconds: number ): void {
const expiryDate = new Date( created.getTime() );
expiryDate.setSeconds( created.getSeconds() + durationInSeconds );

const hideData = {
v: 1,
created: Math.floor( created.getTime() / 1000 ),
reason: reason
};

document.cookie = `${ COOKIE_NAME }=${ encodeURIComponent( JSON.stringify( hideData ) ) }; expires=${ expiryDate.toUTCString() }; path=/; SameSite=None;`;
}
17 changes: 17 additions & 0 deletions test/integration/page/MediaWiki/createTrackingImage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { describe, expect, it, vi, vitest } from 'vitest';
import { createImageCookieSetter } from '@src/page/MediaWiki/createImageCookieSetter';

describe( 'createTrackingImage', () => {
it( 'creates the image cookie setter', () => {
const element = { src: '' };
const documentMock = {
createElement: vi.fn( () => element )
};
vitest.stubGlobal( 'document', documentMock );

createImageCookieSetter( 'fun', 424242, '//en.wikipedia.org/w/index.php?title=Special:HideBanners' );

expect( document.createElement ).toHaveBeenCalledOnce();
expect( element.src ).toBe( 'https://en.wikipedia.org/w/index.php?title=Special%3AHideBanners&duration=424242&category=fundraising&reason=fun' );
} );
} );
17 changes: 17 additions & 0 deletions test/integration/page/MediaWiki/setCookie.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { describe, expect, it } from 'vitest';
import { setCookie } from '@src/page/MediaWiki/setCookie';

describe( 'setCookie', () => {
it( 'sets the cookie', () => {
Object.defineProperty( document, 'cookie', { writable: true, configurable: true, value: '' } );

setCookie( 'testReason', new Date( 'August 29, 1997 02:14:00' ), 99999 );

expect( document.cookie ).toBe( [
'centralnotice_hide_fundraising=%7B%22v%22%3A1%2C%22created%22%3A872813640%2C%22reason%22%3A%22testReason%22%7D;',
'expires=Sat, 30 Aug 1997 04:00:39 GMT;',
'path=/;',
'SameSite=None;'
].join( ' ' ) );
} );
} );

0 comments on commit 353ddda

Please sign in to comment.