Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test consent or pay #1783

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
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
5 changes: 5 additions & 0 deletions .changeset/popular-trees-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@guardian/libs': minor
---

Test for Consent or Pay
52 changes: 48 additions & 4 deletions apps/github-pages/src/components/CmpTest.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
import { cmp, onConsentChange, log } from '@guardian/libs';
import { onMount } from 'svelte';


let subscribed = window.location.search.includes('subscribed');
let isFeatureFlagEnabled = window.location.search.includes('CMP_COP');
// localStorage.setItem('subscribed', window.location.search.includes('subscribed'));

switch (window.location.hash) {
case '#tcfv2':
localStorage.setItem('framework', JSON.stringify('tcfv2'));
Expand Down Expand Up @@ -37,6 +42,13 @@
log('cmp', event);
}

let rejectAllFunc = () => {
cmp.rejectAll().then(() => {
logEvent({ title: 'rejectAll'});
// window.location.reload();
});
};

let clearPreferences = () => {
// clear local storage
// https://documentation.sourcepoint.com/web-implementation/general/cookies-and-local-storage#cmp-local-storage
Expand All @@ -60,6 +72,23 @@
clearPreferences();
};

const toggleSubscribed = () => {
subscribed = !subscribed;
toggleQueryParams('subscribed');
localStorage.setItem('subscribed', JSON.stringify(subscribed));
};

const toggleQueryParams = (param) => {
let queryParams = new URLSearchParams(window.location.search);
queryParams.has(param) ? queryParams.delete(param) : queryParams.append(param, '');
window.location.search = queryParams.toString();
};

const toggleIsFeatureFlagEnabled = () => {
isFeatureFlagEnabled = !isFeatureFlagEnabled;
toggleQueryParams('CMP_COP');
};

$: consentState = {};
$: eventsList = [];

Expand Down Expand Up @@ -91,10 +120,7 @@
}

// do this loads to make sure that doesn't break things
cmp.init({ country });
cmp.init({ country });
cmp.init({ country });
cmp.init({ country });
cmp.init({ country, subscribed: subscribed ?? false });
});
</script>

Expand All @@ -104,6 +130,7 @@
>open privacy manager</button
>
<button on:click={clearPreferences}>clear preferences</button>
<button on:click={rejectAllFunc}>rejectAll</button>
<label class={framework == 'tcfv2' ? 'selected' : 'none'}>
<input
type="radio"
Expand Down Expand Up @@ -133,6 +160,23 @@
in Australia:
<strong>CCPA-like</strong>
</label>
<label class={subscribed ? 'selected' : 'none'}>
<input
type="checkbox"
on:change={toggleSubscribed}
checked={subscribed}
/>
<strong>Subscribed</strong>
</label>

<label class={isFeatureFlagEnabled ? 'selected' : 'none'}>
<input
type="checkbox"
on:change={toggleIsFeatureFlagEnabled}
checked={isFeatureFlagEnabled}
/>
<strong>Feature enabled?</strong>
</label>
</nav>

<div id="consent-state">
Expand Down
8 changes: 6 additions & 2 deletions libs/@guardian/libs/src/consent-management-platform/cmp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ import type {
WillShowPrivacyMessage,
} from './types';

const init = (framework: ConsentFramework, pubData?: PubData): void => {
const init = (
framework: ConsentFramework,
subscribed: boolean,
pubData?: PubData,
): void => {
mark('cmp-init');
initSourcepoint(framework, pubData);
initSourcepoint(framework, pubData, subscribed);
};

const willShowPrivacyMessage: WillShowPrivacyMessage = () =>
Expand Down
23 changes: 12 additions & 11 deletions libs/@guardian/libs/src/consent-management-platform/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ describe('cmp.init', () => {
it('does nothing if CMP is disabled', () => {
disable();

cmp.init({ country: 'GB' });
cmp.init({ country: 'US' });
cmp.init({ country: 'GB', subscribed: true });
cmp.init({ country: 'US', subscribed: true });

expect(CMP.init).not.toHaveBeenCalled();

Expand All @@ -33,33 +33,33 @@ describe('cmp.init', () => {

it('requires country to be set', () => {
expect(() => {
cmp.init({ pubData: {} });
cmp.init({ subscribed: true, pubData: {} });
}).toThrow('required');
});

it('initializes CMP when in the US', () => {
cmp.init({ country: 'US' });
cmp.init({ country: 'US', subscribed: true });
expect(CMP.init).toHaveBeenCalledTimes(1);
});

it('initializes CMP when in Australia', () => {
cmp.init({ country: 'AU' });
cmp.init({ country: 'AU', subscribed: true });
expect(CMP.init).toHaveBeenCalledTimes(1);
});

it('initializes TCF when neither in the US or Australia', () => {
cmp.init({ country: 'GB' });
cmp.init({ country: 'GB', subscribed: true });
expect(CMP.init).toHaveBeenCalledTimes(1);
});
});

// *************** START commercial.dcr.js hotfix ***************
describe('hotfix cmp.init', () => {
it('only initialises once per page', () => {
cmp.init({ country: 'GB' });
cmp.init({ country: 'GB' });
cmp.init({ country: 'GB' });
cmp.init({ country: 'GB' });
cmp.init({ country: 'GB', subscribed: true });
cmp.init({ country: 'GB', subscribed: true });
cmp.init({ country: 'GB', subscribed: true });
cmp.init({ country: 'GB', subscribed: true });
expect(CMP.init).toHaveBeenCalledTimes(1);
expect(window.guCmpHotFix.initialised).toBe(true);
});
Expand All @@ -68,7 +68,7 @@ describe('hotfix cmp.init', () => {
const consoleWarn = jest
.spyOn(global.console, 'warn')
.mockImplementation(() => undefined);
cmp.init({ country: 'GB' });
cmp.init({ country: 'GB', subscribed: true });
const currentVersion = window.guCmpHotFix.cmp?.version;
const mockedVersion = 'X.X.X-mock';

Expand Down Expand Up @@ -106,6 +106,7 @@ describe('hotfix cmp.init', () => {
willShowPrivacyMessage: () => new Promise(() => true),
willShowPrivacyMessageSync: () => true,
hasInitialised: () => true,
rejectAll: () => new Promise(() => undefined),
showPrivacyManager: () => {
console.warn('This is a dummy for showPrivacyManager');
},
Expand Down
10 changes: 8 additions & 2 deletions libs/@guardian/libs/src/consent-management-platform/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getConsentFor as clientGetConsentFor } from './getConsentFor';
import { getFramework } from './getFramework';
import { onConsent as clientOnConsent } from './onConsent';
import { onConsentChange as clientOnConsentChange } from './onConsentChange';
import { rejectAll as clientRejectAll } from './rejectAll';
import {
isServerSide,
cmp as serverCmp,
Expand Down Expand Up @@ -33,7 +34,7 @@ const initialised = new Promise((resolve) => {
resolveInitialised = resolve;
});

const init: InitCMP = ({ pubData, country }) => {
const init: InitCMP = ({ pubData, country, subscribed = true }) => {
if (isDisabled() || isServerSide) {
return;
}
Expand Down Expand Up @@ -61,7 +62,7 @@ const init: InitCMP = ({ pubData, country }) => {

const framework = getFramework(country);

UnifiedCMP.init(framework, pubData ?? {});
UnifiedCMP.init(framework, subscribed, pubData ?? {});

void UnifiedCMP.willShowPrivacyMessage().then((willShowValue) => {
_willShowPrivacyMessage = willShowValue;
Expand Down Expand Up @@ -92,6 +93,10 @@ const showPrivacyManager = () => {
void initialised.then(UnifiedCMP.showPrivacyManager);
};

const rejectAll = isServerSide
? clientRejectAll
: (window.guCmpHotFix.rejectAll ??= clientRejectAll);

export const cmp: CMP = isServerSide
? serverCmp
: (window.guCmpHotFix.cmp ??= {
Expand All @@ -100,6 +105,7 @@ export const cmp: CMP = isServerSide
willShowPrivacyMessageSync,
hasInitialised,
showPrivacyManager,
rejectAll,
version: version,

// special helper methods for disabling CMP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { isGuardianDomain } from './domain';

export const ACCOUNT_ID = 1257;
export const PRIVACY_MANAGER_USNAT = 1068329;
export const PROPERTY_ID = 7417;
export const PROPERTY_ID = 9398;
// export const PROPERTY_ID = 7417;
export const PROPERTY_ID_AUSTRALIA = 13348;
export const PRIVACY_MANAGER_TCFV2 = 106842;
export const PRIVACY_MANAGER_AUSTRALIA = 1178486;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { getCurrentFramework } from './getCurrentFramework';
import { invokeCallbacks } from './onConsentChange';
import { rejectAllForUser } from './tcfv2/api';

const rejectAll = (): Promise<void> =>
// Consider jurisdiction/framework and countries.
new Promise<void>((resolve, reject) => {
console.log('Rejecting all');
if (getCurrentFramework() === 'tcfv2') {
rejectAllForUser()
.then(() => {
invokeCallbacks();
resolve();
})
.catch(() => {
reject(new Error('Unable to reject all'));
});
} else {
reject(new Error('Framework not supported'));
}
});
export { rejectAll };
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const cmp: CMP = {
version: 'n/a',
willShowPrivacyMessage: serverSideWarnAndReturn(Promise.resolve(false)),
willShowPrivacyMessageSync: serverSideWarnAndReturn(false),
rejectAll: serverSideWarnAndReturn(Promise.resolve()),
};

export const onConsent = (): ReturnType<typeof OnConsent> => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const getPropertyHref = (framework: ConsentFramework): Property => {
if (framework == 'aus') {
return 'https://au.theguardian.com';
}
return isGuardianDomain() ? null : 'https://test.theguardian.com';
// return isGuardianDomain() ? null : 'https://test.theguardian.com';
return isGuardianDomain() ? null : 'http://ui-dev';
};

const getPropertyId = (framework: ConsentFramework): number => {
Expand All @@ -40,7 +41,11 @@ const getPropertyId = (framework: ConsentFramework): number => {
return PROPERTY_ID;
};

export const init = (framework: ConsentFramework, pubData = {}): void => {
export const init = (
framework: ConsentFramework,
pubData = {},
subscribed: boolean,
): void => {
stub(framework);

// make sure nothing else on the page has accidentally
Expand Down Expand Up @@ -72,6 +77,8 @@ export const init = (framework: ConsentFramework, pubData = {}): void => {
window.guardian?.config?.tests?.useSourcepointPropertyIdVariant ===
'variant';

const isFeatureFlagEnabled = window.location.search.includes('CMP_COP');

log('cmp', `framework: ${framework}`);
log('cmp', `frameworkMessageType: ${frameworkMessageType}`);

Expand All @@ -82,9 +89,11 @@ export const init = (framework: ConsentFramework, pubData = {}): void => {
baseEndpoint: ENDPOINT,
accountId: ACCOUNT_ID,
propertyHref: getPropertyHref(framework),
propertyId: getPropertyId(framework),
targetingParams: {
framework,
},
campaignEnv: 'stage',
pubData: { ...pubData, cmpInitTimeUtc: new Date().getTime() },

// ccpa or gdpr object added below
Expand Down Expand Up @@ -142,6 +151,18 @@ export const init = (framework: ConsentFramework, pubData = {}): void => {
)
) {
setTimeout(invokeCallbacks, 0);

if (
choiceTypeID === SourcePointChoiceTypes.RejectAll &&
message_type === 'gdpr' &&
!subscribed &&
isFeatureFlagEnabled
) {
console.log('User has rejected all');
window.location.replace(
`https://support.theguardian.com/uk/contribute?redirectUrl=${window.location.href}`,
);
}
}
},
onPrivacyManagerAction: function (message_type, pmData) {
Expand Down Expand Up @@ -198,6 +219,8 @@ export const init = (framework: ConsentFramework, pubData = {}): void => {
window._sp_.config.gdpr = {
targetingParams: {
framework,
subscribed,
isFeatureFlagEnabled,
},
};
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type Command =
| 'ping'
| 'addEventListener'
| 'removeEventListener'
| 'postRejectAll'
| 'getCustomVendorConsents'; // Sourcepoint addition https://documentation.sourcepoint.com/web-implementation/sourcepoint-gdpr-and-tcf-v2-support/__tcfapi-getcustomvendorconsents-api

const api = (command: Command) =>
Expand Down Expand Up @@ -33,3 +34,6 @@ export const getTCData = (): Promise<TCData> =>

export const getCustomVendorConsents = (): Promise<CustomVendorConsents> =>
api('getCustomVendorConsents') as Promise<CustomVendorConsents>;

export const rejectAllForUser = (): Promise<void> =>
api('postRejectAll') as Promise<void>;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type CMP = {
willShowPrivacyMessageSync: () => boolean;
hasInitialised: () => boolean;
showPrivacyManager: () => void;
rejectAll: () => Promise<void>;
version: string;
__isDisabled: () => boolean;
__disable: () => void;
Expand All @@ -21,6 +22,7 @@ export type CMP = {
export type InitCMP = (arg0: {
pubData?: PubData;
country?: CountryCode;
subscribed?: boolean;
}) => void;

export type OnConsentChange = (
Expand All @@ -46,7 +48,11 @@ export interface PubData {
[propName: string]: unknown;
}
export interface SourcepointImplementation {
init: (framework: ConsentFramework, pubData?: PubData) => void;
init: (
framework: ConsentFramework,
subscribed: boolean,
pubData?: PubData,
) => void;
willShowPrivacyMessage: WillShowPrivacyMessage;
showPrivacyManager: () => void;
}
Expand Down
Loading
Loading