From f18dbe65db924cbfe1e06cc89cb2d17db17de546 Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Mon, 8 Apr 2024 12:05:00 +0100 Subject: [PATCH 01/52] Copied all changes in CMP repo --- .../__fixtures__/api.getGPPData.fail.json | 6 + .../__fixtures__/api.getGPPData.success.json | 11 ++ .../consent-management-platform/ccpa/api.ts | 15 +- .../ccpa/getConsentState.ts | 6 +- .../src/consent-management-platform/cmp.ts | 2 +- .../lib/sourcepointConfig.ts | 2 +- .../sourcepoint.test.js | 8 +- .../sourcepoint.ts | 22 ++- .../src/consent-management-platform/stub.ts | 2 + .../stub_gpp_ccpa.js | 176 +++++++++++------- .../consent-management-platform/types/ccpa.ts | 14 ++ .../types/window.d.ts | 17 +- 12 files changed, 193 insertions(+), 88 deletions(-) create mode 100644 libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.fail.json create mode 100644 libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.success.json diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.fail.json b/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.fail.json new file mode 100644 index 000000000..c43661dd0 --- /dev/null +++ b/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.fail.json @@ -0,0 +1,6 @@ +{ + "applicableSections": [], + "gppString": "DBAA", + "gppVersion": "1.1", + "parsedSections": {} +} diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.success.json b/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.success.json new file mode 100644 index 000000000..6ddb99d65 --- /dev/null +++ b/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.success.json @@ -0,0 +1,11 @@ +{ + "applicableSections": [7], + "gppString": "DBABLA~BEAgAAAAAgA.QA", + "gppVersion": "1.1", + "parsedSections": { + "usnatv1": { + "Version": 1, + "SaleOptOut": 2 + } + } +} diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.ts b/libs/@guardian/libs/src/consent-management-platform/ccpa/api.ts index c3707468c..6f1a18995 100644 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.ts +++ b/libs/@guardian/libs/src/consent-management-platform/ccpa/api.ts @@ -1,20 +1,19 @@ -import type { CCPAData } from '../types/ccpa'; +import type { GPPData } from '../types/ccpa'; -type Command = 'getUSPData'; +type Command = 'ping'; const api = (command: Command) => new Promise((resolve, reject) => { - if (window.__uspapi) { - window.__uspapi(command, 1, (result, success) => + if (window.__gpp) { + window.__gpp(command, (result, success) => success ? resolve(result) : /* istanbul ignore next */ reject(new Error(`Unable to get ${command} data`)), ); } else { - reject(new Error('No __uspapi found on window')); + reject(new Error('No __gpp found on window')); } }); - -export const getUSPData = (): Promise => - api('getUSPData') as Promise; +export const getGPPData = (): Promise => + api('ping') as Promise; diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts b/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts index f66f2b15c..4e3007968 100644 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts +++ b/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts @@ -1,11 +1,11 @@ import type { CCPAConsentState } from '../types/ccpa'; -import { getUSPData } from './api'; +import { getGPPData } from './api'; // get the current consent state using the official IAB method export const getConsentState: () => Promise = async () => { - const uspData = await getUSPData(); + const gppData = await getGPPData(); return { - doNotSell: uspData.uspString.charAt(2) === 'Y', + doNotSell: gppData.parsedSections.usnatv1?.SaleOptOut !== 2, }; }; diff --git a/libs/@guardian/libs/src/consent-management-platform/cmp.ts b/libs/@guardian/libs/src/consent-management-platform/cmp.ts index 9f23239bd..5fac4e542 100644 --- a/libs/@guardian/libs/src/consent-management-platform/cmp.ts +++ b/libs/@guardian/libs/src/consent-management-platform/cmp.ts @@ -30,7 +30,7 @@ function showPrivacyManager(): void { window._sp_?.gdpr?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_TCFV2); break; case 'ccpa': - window._sp_?.ccpa?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_CCPA); + window._sp_?.usnat?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_CCPA); break; case 'aus': window._sp_?.ccpa?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_AUSTRALIA); diff --git a/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts b/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts index 08e4a313f..b921385cb 100644 --- a/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts +++ b/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts @@ -1,7 +1,7 @@ import { isGuardianDomain } from './domain'; export const ACCOUNT_ID = 1257; -export const PRIVACY_MANAGER_CCPA = 540252; +export const PRIVACY_MANAGER_CCPA = 1068329; export const PRIVACY_MANAGER_TCFV2 = 106842; export const PRIVACY_MANAGER_AUSTRALIA = 540341; diff --git a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js index d78aaebde..ecb21b46f 100644 --- a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js @@ -9,6 +9,7 @@ describe('Sourcepoint unified', () => { beforeEach(() => { window.__tcfapi = undefined; window.__uspapi = undefined; + window.__gpp = undefined; }); afterEach(() => { window._sp_ = undefined; @@ -40,13 +41,17 @@ describe('Sourcepoint unified', () => { expect(window._sp_.config.ccpa).toBeUndefined(); expect(window.__tcfapi).toBeDefined(); expect(window.__uspapi).toBeUndefined(); + expect(window.__gpp).toBeUndefined(); } else if (framework == 'ccpa') { - expect(window._sp_.config.ccpa.targetingParams.framework).toEqual( + expect(window._sp_.config.usnat.includeUspApi).toBeTruthy(); + expect(window._sp_.config.usnat.transitionCCPAAuth).toBeTruthy(); + expect(window._sp_.config.usnat.targetingParams.framework).toEqual( framework, ); expect(window._sp_.config.gdpr).toBeUndefined; expect(window.__uspapi).toBeDefined(); expect(window.__tcfapi).toBeUndefined(); + expect(window.__gpp).toBeDefined(); } else if (framework == 'aus') { expect(window._sp_.config.ccpa.targetingParams.framework).toEqual( framework, @@ -54,6 +59,7 @@ describe('Sourcepoint unified', () => { expect(window._sp_.config.gdpr).toBeUndefined; expect(window.__uspapi).toBeDefined(); expect(window.__tcfapi).toBeUndefined(); + expect(window.__gpp).toBeUndefined(); } }, ); diff --git a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts index cd36c3740..8ab2c77f2 100644 --- a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts +++ b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts @@ -39,7 +39,22 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { // invoke callbacks before we receive Sourcepoint events invokeCallbacks(); - const frameworkMessageType: string = framework == 'tcfv2' ? 'gdpr' : 'ccpa'; + let frameworkMessageType: string; + switch (framework) { + case 'tcfv2': + frameworkMessageType = 'gdpr'; + break; + case 'ccpa': + frameworkMessageType = 'usnat'; + break; + + case 'aus': + frameworkMessageType = 'ccpa'; + break; + default: + frameworkMessageType = 'gdpr'; + break; + } log('cmp', `framework: ${framework}`); log('cmp', `frameworkMessageType: ${frameworkMessageType}`); @@ -51,6 +66,7 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { baseEndpoint: ENDPOINT, accountId: ACCOUNT_ID, propertyHref: getProperty(framework), + campaignEnv: 'stage', targetingParams: { framework, }, @@ -151,10 +167,12 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { }; break; case 'ccpa': - window._sp_.config.ccpa = { + window._sp_.config.usnat = { targetingParams: { framework, }, + includeUspApi: true, + transitionCCPAAuth: true, }; break; case 'aus': diff --git a/libs/@guardian/libs/src/consent-management-platform/stub.ts b/libs/@guardian/libs/src/consent-management-platform/stub.ts index d034d5730..91d073870 100644 --- a/libs/@guardian/libs/src/consent-management-platform/stub.ts +++ b/libs/@guardian/libs/src/consent-management-platform/stub.ts @@ -1,3 +1,4 @@ +import { stub_gpp_ccpa } from './stub_gpp_ccpa'; import { stub_tcfv2 } from './stub_tcfv2'; import { stub_uspapi_ccpa } from './stub_uspapi_ccpa'; import type { ConsentFramework } from './types'; @@ -12,6 +13,7 @@ export const stub = (framework: ConsentFramework): void => { stub_tcfv2(); break; case 'ccpa': + stub_gpp_ccpa(); stub_uspapi_ccpa(); break; case 'aus': diff --git a/libs/@guardian/libs/src/consent-management-platform/stub_gpp_ccpa.js b/libs/@guardian/libs/src/consent-management-platform/stub_gpp_ccpa.js index 091dd2ece..490a24901 100644 --- a/libs/@guardian/libs/src/consent-management-platform/stub_gpp_ccpa.js +++ b/libs/@guardian/libs/src/consent-management-platform/stub_gpp_ccpa.js @@ -3,14 +3,13 @@ // Reference : https://docs.sourcepoint.com/hc/en-us/articles/18007731422099-Enable-GPP-Multi-State-Privacy-String-MSPS-with-U-S-Privacy-CCPA-solution export const stub_gpp_ccpa = () => { (window.__gpp_addFrame = function (e) { - if (!window.frames[e]) { + if (!window.frames[e]) if (document.body) { var t = document.createElement('iframe'); (t.style.cssText = 'display:none'), (t.name = e), document.body.appendChild(t); } else window.setTimeout(window.__gpp_addFrame, 10, e); - } }), (window.__gpp_stub = function () { var e = arguments; @@ -18,79 +17,114 @@ export const stub_gpp_ccpa = () => { ((__gpp.queue = __gpp.queue || []), (__gpp.events = __gpp.events || []), !e.length || (1 == e.length && 'queue' == e[0])) - ) { + ) return __gpp.queue; - } if (1 == e.length && 'events' == e[0]) return __gpp.events; var t = e[0], p = e.length > 1 ? e[1] : null, - n = e.length > 2 ? e[2] : null; - if ('ping' === t) { - return { - gppVersion: '1.0', - cmpStatus: 'stub', - cmpDisplayStatus: 'hidden', - supportedAPIs: ['tcfeuv2', 'tcfcav2', 'uspv1'], - cmpId: 31, - }; - } - if ('addEventListener' === t) { - 'lastId' in __gpp || (__gpp.lastId = 0), __gpp.lastId++; - var a = __gpp.lastId; - return ( - __gpp.events.push({ id: a, callback: p, parameter: n }), + s = e.length > 2 ? e[2] : null; + if ('ping' === t) + p( { - eventName: 'listenerRegistered', - listenerId: a, - data: !0, - pingData: { - gppVersion: '1.0', - cmpStatus: 'stub', - cmpDisplayStatus: 'hidden', - supportedAPIs: ['tcfeuv2', 'tcfva', 'usnat'], - cmpId: 31, - }, - } - ); - } - if ('removeEventListener' === t) { - for (var s = !1, i = 0; i < __gpp.events.length; i++) { - if (__gpp.events[i].id == n) { - __gpp.events.splice(i, 1), (s = !0); - break; - } - } - return { - eventName: 'listenerRemoved', - listenerId: n, - data: s, - pingData: { - gppVersion: '1.0', + gppVersion: '1.1', cmpStatus: 'stub', cmpDisplayStatus: 'hidden', - supportedAPIs: ['tcfeuv2', 'tcfva', 'usnat'], - cmpId: 31, - }, - }; - } - return 'getGPPData' === t - ? { - sectionId: 3, - gppVersion: 1, + signalStatus: 'not ready', + supportedAPIs: [ + '2:tcfeuv2', + '5:tcfcav1', + '6:uspv1', + '7:usnatv1', + '8:uscav1', + '9:usvav1', + '10:uscov1', + '11:usutv1', + '12:usctv1', + ], + cmpId: 0, sectionList: [], - applicableSections: [0], + applicableSections: [], gppString: '', + parsedSections: {}, + }, + !0, + ); + else if ('addEventListener' === t) { + 'lastId' in __gpp || (__gpp.lastId = 0), __gpp.lastId++; + var n = __gpp.lastId; + __gpp.events.push({ id: n, callback: p, parameter: s }), + p( + { + eventName: 'listenerRegistered', + listenerId: n, + data: !0, + pingData: { + gppVersion: '1.1', + cmpStatus: 'stub', + cmpDisplayStatus: 'hidden', + signalStatus: 'not ready', + supportedAPIs: [ + '2:tcfeuv2', + '5:tcfcav1', + '6:uspv1', + '7:usnatv1', + '8:uscav1', + '9:usvav1', + '10:uscov1', + '11:usutv1', + '12:usctv1', + ], + cmpId: 0, + sectionList: [], + applicableSections: [], + gppString: '', + parsedSections: {}, + }, + }, + !0, + ); + } else if ('removeEventListener' === t) { + for (var a = !1, i = 0; i < __gpp.events.length; i++) + if (__gpp.events[i].id == s) { + __gpp.events.splice(i, 1), (a = !0); + break; + } + p( + { + eventName: 'listenerRemoved', + listenerId: s, + data: a, pingData: { - gppVersion: '1.0', + gppVersion: '1.1', cmpStatus: 'stub', cmpDisplayStatus: 'hidden', - supportedAPIs: ['tcfeuv2', 'tcfva', 'usnat'], - cmpId: 31, + signalStatus: 'not ready', + supportedAPIs: [ + '2:tcfeuv2', + '5:tcfcav1', + '6:uspv1', + '7:usnatv1', + '8:uscav1', + '9:usvav1', + '10:uscov1', + '11:usutv1', + '12:usctv1', + ], + cmpId: 0, + sectionList: [], + applicableSections: [], + gppString: '', + parsedSections: {}, }, - } - : 'hasSection' === t || 'getSection' === t || 'getField' === t - ? null - : void __gpp.queue.push([].slice.apply(e)); + }, + !0, + ); + } else + 'hasSection' === t + ? p(!1, !0) + : 'getSection' === t || 'getField' === t + ? p(null, !0) + : __gpp.queue.push([].slice.apply(e)); }), (window.__gpp_msghandler = function (e) { var t = 'string' == typeof e.data; @@ -100,21 +134,21 @@ export const stub_gpp_ccpa = () => { p = null; } if ('object' == typeof p && null !== p && '__gppCall' in p) { - var n = p.__gppCall; + var s = p.__gppCall; window.__gpp( - n.command, - function (p, a) { - var s = { + s.command, + function (p, n) { + var a = { __gppReturn: { returnValue: p, - success: a, - callId: n.callId, + success: n, + callId: s.callId, }, }; - e.source.postMessage(t ? JSON.stringify(s) : s, '*'); + e.source.postMessage(t ? JSON.stringify(a) : a, '*'); }, - 'parameter' in n ? n.parameter : null, - 'version' in n ? n.version : 1, + 'parameter' in s ? s.parameter : null, + 'version' in s ? s.version : '1.1', ); } }), diff --git a/libs/@guardian/libs/src/consent-management-platform/types/ccpa.ts b/libs/@guardian/libs/src/consent-management-platform/types/ccpa.ts index 49e6e5ce2..7e3fe89d5 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/ccpa.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/ccpa.ts @@ -6,3 +6,17 @@ export interface CCPAData { version: number; uspString: string; } + +interface GppParsedSections { + usnatv1?: { + Version: number; + SaleOptOut: number; + }; +} + +export interface GPPData { + gppVersion: number; + gppString: string; + applicableSections: number[]; + parsedSections: GppParsedSections; +} diff --git a/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts b/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts index acfc4698d..123c70f0b 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts @@ -3,7 +3,7 @@ import type { Property } from '../lib/property'; import type { EndPoint } from '../lib/sourcepointConfig'; import type { onConsent } from '../onConsent'; import type { onConsentChange } from '../onConsentChange'; -import type { CCPAData } from './ccpa'; +import type { CCPAData, GPPData } from './ccpa'; import type { TCData } from './tcfv2/TCData'; import type { CMP, ConsentFramework, PubData } from '.'; @@ -33,6 +33,7 @@ declare global { accountId: number; propertyHref: Property; propertyId?: string; + campaignEnv?: string; targetingParams: { framework: ConsentFramework; }; @@ -46,6 +47,13 @@ declare global { framework: ConsentFramework; }; }; + usnat?: { + includeUspApi?: boolean; + transitionCCPAAuth?: boolean; + targetingParams?: { + framework: ConsentFramework; + }; + }; pubData: PubData; events?: { onMessageReceiveData: ( @@ -82,6 +90,9 @@ declare global { ccpa?: { loadPrivacyManagerModal?: (id: number) => void; }; + usnat?: { + loadPrivacyManagerModal?: (id: number) => void; + }; }; // IAB interfaces - only one should be present at a time @@ -96,5 +107,9 @@ declare global { callback: (tcData: TCData, success: boolean) => void, vendorIDs?: number[], ) => void; + __gpp?: ( + command: string, + callback: (gppData: GPPData, success: boolean) => void, + ) => void; } } From 7f1bd12c0e06ddcbe39784c1812f7248e53f78c6 Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:48:04 +0100 Subject: [PATCH 02/52] updated all tests --- .../ccpa/api.test.js | 14 +++++------- .../ccpa/getConsentState.test.js | 22 ++++++++++++++----- .../onConsentChange.test.js | 14 +++++++----- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.test.js b/libs/@guardian/libs/src/consent-management-platform/ccpa/api.test.js index 9af36b2db..80c9ea29f 100644 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/ccpa/api.test.js @@ -1,17 +1,13 @@ -import { getUSPData } from './api.ts'; +import { getGPPData } from './api.ts'; it('calls the correct IAB api with the correct methods', async () => { - expect(getUSPData()).rejects.toThrow(); + expect(getGPPData()).rejects.toThrow(); - window.__uspapi = jest.fn((a, b, cb) => { + window.__gpp = jest.fn((a, cb) => { cb({}, true); }); - await getUSPData(); + await getGPPData(); - expect(window.__uspapi).toHaveBeenCalledWith( - 'getUSPData', - expect.any(Number), - expect.any(Function), - ); + expect(window.__gpp).toHaveBeenCalledWith('ping', expect.any(Function)); }); diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js b/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js index 675704ea4..82d4e1756 100644 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js @@ -1,15 +1,27 @@ -import uspData from './__fixtures__/api.getUSPData.json'; -import { getUSPData } from './api.ts'; +import gppDataFail from './__fixtures__/api.getGPPData.fail.json'; +import gppDataSuccess from './__fixtures__/api.getGPPData.success.json'; +import { getGPPData } from './api.ts'; import { getConsentState } from './getConsentState.ts'; jest.mock('./api'); -getUSPData.mockResolvedValue(uspData); +getGPPData.mockResolvedValue(gppDataSuccess); describe('getConsentState', () => { - it('gets the consent state correctly', async () => { + it('gets the gpp consent state correctly', async () => { + getGPPData.mockResolvedValue(gppDataSuccess); + + const { doNotSell } = await getConsentState(); + expect(getGPPData).toHaveBeenCalledTimes(1); + + expect(doNotSell).toBe(false); + }); + + it('gets the usp consent state correctly', async () => { + getGPPData.mockResolvedValue(gppDataFail); + const { doNotSell } = await getConsentState(); - expect(getUSPData).toHaveBeenCalledTimes(1); + expect(getGPPData).toHaveBeenCalledTimes(1); expect(doNotSell).toBe(true); }); }); diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js index 42d92491d..d022c8273 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js @@ -1,5 +1,5 @@ import ausData from './aus/__fixtures__/api.getUSPData.json'; -import uspData from './ccpa/__fixtures__/api.getUSPData.json'; +import gppData from './ccpa/__fixtures__/api.getGPPData.success.json'; import { setCurrentFramework } from './getCurrentFramework.ts'; import { _, invokeCallbacks, onConsentChange } from './onConsentChange.ts'; import customVendorConsents from './tcfv2/__fixtures__/api.getCustomVendorConsents.json'; @@ -11,6 +11,7 @@ const resolveAllPromises = () => beforeEach(() => { window.__uspapi = undefined; window.__tcfapi = undefined; + window.__gpp = undefined; window.guCmpHotFix = undefined; }); @@ -22,8 +23,8 @@ it('throws an error if no framework is present', () => { describe('under CCPA', () => { beforeEach(() => { - window.__uspapi = jest.fn((command, b, callback) => { - if (command === 'getUSPData') callback(uspData, true); + window.__gpp = jest.fn((command, callback) => { + if (command === 'ping') callback(gppData, true); }); setCurrentFramework('ccpa'); @@ -63,7 +64,7 @@ describe('under CCPA', () => { expect(callback).toHaveBeenCalledTimes(1); - uspData.uspString = '1YNN'; + gppData.parsedSections.usnatv1.SaleOptOut = 1; invokeCallbacks(); await resolveAllPromises(); @@ -81,7 +82,7 @@ describe('under CCPA', () => { const callback3 = jest.fn(() => setCallbackLastExecuted(3)); const callback4 = jest.fn(() => setCallbackLastExecuted(4)); - uspData.uspString = '1YYN'; + gppData.parsedSections.usnatv1.SaleOptOut = 1; // callback 3 and 4 registered first with final flag onConsentChange(callback3, true); @@ -100,7 +101,8 @@ describe('under CCPA', () => { expect(callbackLastExecuted[4]).toBeLessThan(callbackLastExecuted[1]); expect(callbackLastExecuted[1]).toBeLessThan(callbackLastExecuted[2]); - uspData.uspString = '1YNN'; + gppData.parsedSections.usnatv1.SaleOptOut = 2; + invokeCallbacks(); await resolveAllPromises(); From 8ec83b42c7925d499610f55d3cf1b32e905ea559 Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:20:11 +0100 Subject: [PATCH 03/52] added usnat and using instead of ccpa --- libs/@guardian/libs/src/consent-management-platform/cmp.ts | 2 +- .../libs/src/consent-management-platform/getFramework.ts | 2 +- .../libs/src/consent-management-platform/sourcepoint.ts | 4 ++-- .../libs/src/consent-management-platform/types/index.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/@guardian/libs/src/consent-management-platform/cmp.ts b/libs/@guardian/libs/src/consent-management-platform/cmp.ts index 5fac4e542..27c8250e6 100644 --- a/libs/@guardian/libs/src/consent-management-platform/cmp.ts +++ b/libs/@guardian/libs/src/consent-management-platform/cmp.ts @@ -29,7 +29,7 @@ function showPrivacyManager(): void { case 'tcfv2': window._sp_?.gdpr?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_TCFV2); break; - case 'ccpa': + case 'usnat': window._sp_?.usnat?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_CCPA); break; case 'aus': diff --git a/libs/@guardian/libs/src/consent-management-platform/getFramework.ts b/libs/@guardian/libs/src/consent-management-platform/getFramework.ts index 190dd249f..80229166b 100644 --- a/libs/@guardian/libs/src/consent-management-platform/getFramework.ts +++ b/libs/@guardian/libs/src/consent-management-platform/getFramework.ts @@ -5,7 +5,7 @@ export const getFramework = (countryCode: CountryCode): ConsentFramework => { let framework: ConsentFramework; switch (countryCode) { case 'US': - framework = 'ccpa'; + framework = 'usnat'; break; case 'AU': diff --git a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts index 8ab2c77f2..16182492c 100644 --- a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts +++ b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts @@ -44,7 +44,7 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { case 'tcfv2': frameworkMessageType = 'gdpr'; break; - case 'ccpa': + case 'usnat': frameworkMessageType = 'usnat'; break; @@ -166,7 +166,7 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { }, }; break; - case 'ccpa': + case 'usnat': window._sp_.config.usnat = { targetingParams: { framework, diff --git a/libs/@guardian/libs/src/consent-management-platform/types/index.ts b/libs/@guardian/libs/src/consent-management-platform/types/index.ts index eadebdc13..bcf10227a 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/index.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/index.ts @@ -4,7 +4,7 @@ import type { AUSConsentState } from './aus'; import type { CCPAConsentState } from './ccpa'; import type { TCFv2ConsentState } from './tcfv2'; -export type ConsentFramework = 'tcfv2' | 'ccpa' | 'aus'; +export type ConsentFramework = 'tcfv2' | 'ccpa' | 'aus' | 'usnat'; export type CMP = { init: InitCMP; From eafc632ccc7858b357400128eed742451cc8d31c Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:18:06 +0100 Subject: [PATCH 04/52] Added todo comment --- .../libs/src/consent-management-platform/sourcepoint.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts index 16182492c..14a977f5b 100644 --- a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts +++ b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.ts @@ -47,7 +47,6 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { case 'usnat': frameworkMessageType = 'usnat'; break; - case 'aus': frameworkMessageType = 'ccpa'; break; @@ -66,7 +65,7 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { baseEndpoint: ENDPOINT, accountId: ACCOUNT_ID, propertyHref: getProperty(framework), - campaignEnv: 'stage', + campaignEnv: 'stage', // TODO: REMOVE AFTER TESTING targetingParams: { framework, }, @@ -171,7 +170,7 @@ export const init = (framework: ConsentFramework, pubData = {}): void => { targetingParams: { framework, }, - includeUspApi: true, + includeUspApi: true, // TODO: TO CONFIRM transitionCCPAAuth: true, }; break; From efbacf63df7907865dd48ff48a7da0765a1528a8 Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Tue, 9 Apr 2024 12:18:27 +0100 Subject: [PATCH 05/52] Fixed stub name --- .../libs/src/consent-management-platform/stub.ts | 8 ++++---- .../{stub_gpp_ccpa.js => stub_gpp_usnat.js} | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename libs/@guardian/libs/src/consent-management-platform/{stub_gpp_ccpa.js => stub_gpp_usnat.js} (99%) diff --git a/libs/@guardian/libs/src/consent-management-platform/stub.ts b/libs/@guardian/libs/src/consent-management-platform/stub.ts index 91d073870..5680c6d68 100644 --- a/libs/@guardian/libs/src/consent-management-platform/stub.ts +++ b/libs/@guardian/libs/src/consent-management-platform/stub.ts @@ -1,4 +1,4 @@ -import { stub_gpp_ccpa } from './stub_gpp_ccpa'; +import { stub_gpp_usnat } from './stub_gpp_usnat'; import { stub_tcfv2 } from './stub_tcfv2'; import { stub_uspapi_ccpa } from './stub_uspapi_ccpa'; import type { ConsentFramework } from './types'; @@ -12,9 +12,9 @@ export const stub = (framework: ConsentFramework): void => { case 'tcfv2': stub_tcfv2(); break; - case 'ccpa': - stub_gpp_ccpa(); - stub_uspapi_ccpa(); + case 'usnat': + stub_gpp_usnat(); + stub_uspapi_ccpa(); // TODO: TO bE confirmed break; case 'aus': stub_uspapi_ccpa(); diff --git a/libs/@guardian/libs/src/consent-management-platform/stub_gpp_ccpa.js b/libs/@guardian/libs/src/consent-management-platform/stub_gpp_usnat.js similarity index 99% rename from libs/@guardian/libs/src/consent-management-platform/stub_gpp_ccpa.js rename to libs/@guardian/libs/src/consent-management-platform/stub_gpp_usnat.js index 490a24901..02fd20168 100644 --- a/libs/@guardian/libs/src/consent-management-platform/stub_gpp_ccpa.js +++ b/libs/@guardian/libs/src/consent-management-platform/stub_gpp_usnat.js @@ -1,7 +1,7 @@ /* eslint-disable -- this is third party code */ /* istanbul ignore file */ // Reference : https://docs.sourcepoint.com/hc/en-us/articles/18007731422099-Enable-GPP-Multi-State-Privacy-String-MSPS-with-U-S-Privacy-CCPA-solution -export const stub_gpp_ccpa = () => { +export const stub_gpp_usnat = () => { (window.__gpp_addFrame = function (e) { if (!window.frames[e]) if (document.body) { From c306d447c75353880d96d6db0e48b0ed6f884a2e Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:42:16 +0100 Subject: [PATCH 06/52] Update ccpa to usnat --- .../consent-management-platform/aus/api.ts | 2 +- .../ccpa/getConsentState.test.js | 27 -------------- .../ccpa/getConsentState.ts | 11 ------ .../src/consent-management-platform/cmp.ts | 4 +- .../lib/sourcepointConfig.ts | 2 +- .../onConsent.test.ts | 2 +- .../onConsentChange.enhanced.test.ts | 4 +- .../onConsentChange.test.js | 6 +-- .../onConsentChange.ts | 4 +- .../types/index.ts | 4 +- .../types/{ccpa.ts => usnat.ts} | 2 +- .../types/window.d.ts | 2 +- .../__fixtures__/api.getGPPData.canSell.json} | 0 .../api.getGPPData.doNotSell.json | 11 ++++++ .../__fixtures__/api.getGPPData.fail.json | 0 .../__fixtures__/api.getUSPData.json | 0 .../{ccpa => usnat}/api.test.js | 2 +- .../{ccpa => usnat}/api.ts | 2 +- .../usnat/getConsentState.test.js | 37 +++++++++++++++++++ .../usnat/getConsentState.ts | 12 ++++++ 20 files changed, 78 insertions(+), 56 deletions(-) delete mode 100644 libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js delete mode 100644 libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts rename libs/@guardian/libs/src/consent-management-platform/types/{ccpa.ts => usnat.ts} (89%) rename libs/@guardian/libs/src/consent-management-platform/{ccpa/__fixtures__/api.getGPPData.success.json => usnat/__fixtures__/api.getGPPData.canSell.json} (100%) create mode 100644 libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.doNotSell.json rename libs/@guardian/libs/src/consent-management-platform/{ccpa => usnat}/__fixtures__/api.getGPPData.fail.json (100%) rename libs/@guardian/libs/src/consent-management-platform/{ccpa => usnat}/__fixtures__/api.getUSPData.json (100%) rename libs/@guardian/libs/src/consent-management-platform/{ccpa => usnat}/api.test.js (87%) rename libs/@guardian/libs/src/consent-management-platform/{ccpa => usnat}/api.ts (90%) create mode 100644 libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.test.js create mode 100644 libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.ts diff --git a/libs/@guardian/libs/src/consent-management-platform/aus/api.ts b/libs/@guardian/libs/src/consent-management-platform/aus/api.ts index c3707468c..e650f7414 100644 --- a/libs/@guardian/libs/src/consent-management-platform/aus/api.ts +++ b/libs/@guardian/libs/src/consent-management-platform/aus/api.ts @@ -1,4 +1,4 @@ -import type { CCPAData } from '../types/ccpa'; +import type { CCPAData } from '../types/usnat'; type Command = 'getUSPData'; diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js b/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js deleted file mode 100644 index 82d4e1756..000000000 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.test.js +++ /dev/null @@ -1,27 +0,0 @@ -import gppDataFail from './__fixtures__/api.getGPPData.fail.json'; -import gppDataSuccess from './__fixtures__/api.getGPPData.success.json'; -import { getGPPData } from './api.ts'; -import { getConsentState } from './getConsentState.ts'; - -jest.mock('./api'); -getGPPData.mockResolvedValue(gppDataSuccess); - -describe('getConsentState', () => { - it('gets the gpp consent state correctly', async () => { - getGPPData.mockResolvedValue(gppDataSuccess); - - const { doNotSell } = await getConsentState(); - expect(getGPPData).toHaveBeenCalledTimes(1); - - expect(doNotSell).toBe(false); - }); - - it('gets the usp consent state correctly', async () => { - getGPPData.mockResolvedValue(gppDataFail); - - const { doNotSell } = await getConsentState(); - - expect(getGPPData).toHaveBeenCalledTimes(1); - expect(doNotSell).toBe(true); - }); -}); diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts b/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts deleted file mode 100644 index 4e3007968..000000000 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/getConsentState.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { CCPAConsentState } from '../types/ccpa'; -import { getGPPData } from './api'; - -// get the current consent state using the official IAB method -export const getConsentState: () => Promise = async () => { - const gppData = await getGPPData(); - - return { - doNotSell: gppData.parsedSections.usnatv1?.SaleOptOut !== 2, - }; -}; diff --git a/libs/@guardian/libs/src/consent-management-platform/cmp.ts b/libs/@guardian/libs/src/consent-management-platform/cmp.ts index 27c8250e6..2b4faba55 100644 --- a/libs/@guardian/libs/src/consent-management-platform/cmp.ts +++ b/libs/@guardian/libs/src/consent-management-platform/cmp.ts @@ -2,8 +2,8 @@ import { getCurrentFramework } from './getCurrentFramework'; import { mark } from './lib/mark'; import { PRIVACY_MANAGER_AUSTRALIA, - PRIVACY_MANAGER_CCPA, PRIVACY_MANAGER_TCFV2, + PRIVACY_MANAGER_USNAT, } from './lib/sourcepointConfig'; import { init as initSourcepoint, @@ -30,7 +30,7 @@ function showPrivacyManager(): void { window._sp_?.gdpr?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_TCFV2); break; case 'usnat': - window._sp_?.usnat?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_CCPA); + window._sp_?.usnat?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_USNAT); break; case 'aus': window._sp_?.ccpa?.loadPrivacyManagerModal?.(PRIVACY_MANAGER_AUSTRALIA); diff --git a/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts b/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts index b921385cb..ad2763dde 100644 --- a/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts +++ b/libs/@guardian/libs/src/consent-management-platform/lib/sourcepointConfig.ts @@ -1,7 +1,7 @@ import { isGuardianDomain } from './domain'; export const ACCOUNT_ID = 1257; -export const PRIVACY_MANAGER_CCPA = 1068329; +export const PRIVACY_MANAGER_USNAT = 1068329; // TODO: THIS MAY CHANGE. SEE MESSAGE IN PORTAL export const PRIVACY_MANAGER_TCFV2 = 106842; export const PRIVACY_MANAGER_AUSTRALIA = 540341; diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts b/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts index 9d1002383..dc00f1448 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts @@ -2,7 +2,7 @@ import { onConsent } from './onConsent'; import { onConsentChange } from './onConsentChange'; import type { ConsentState, OnConsentChangeCallback } from './types'; import type { AUSConsentState } from './types/aus'; -import type { CCPAConsentState } from './types/ccpa'; +import type { CCPAConsentState } from './types/usnat'; import type { TCFv2ConsentState } from './types/tcfv2'; jest.mock('./onConsentChange'); diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts index eaf55acfd..da598775a 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts @@ -1,11 +1,11 @@ import { getConsentState as getAUSConsentState } from './aus/getConsentState'; -import { getConsentState as getCCPAConsentState } from './ccpa/getConsentState'; +import { getConsentState as getCCPAConsentState } from './usnat/getConsentState'; import { setCurrentFramework, unsetFramework } from './getCurrentFramework'; import { _ } from './onConsentChange'; import { getConsentState as getTCFv2ConsentState } from './tcfv2/getConsentState'; import type { ConsentFramework, ConsentState } from './types'; import type { AUSConsentState } from './types/aus'; -import type { CCPAConsentState } from './types/ccpa'; +import type { CCPAConsentState } from './types/usnat'; import type { TCFv2ConsentState } from './types/tcfv2'; jest.mock('./tcfv2/getConsentState'); diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js index d022c8273..9da438778 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js @@ -1,5 +1,5 @@ import ausData from './aus/__fixtures__/api.getUSPData.json'; -import gppData from './ccpa/__fixtures__/api.getGPPData.success.json'; +import gppData from './usnat/__fixtures__/api.getGPPData.success.json'; import { setCurrentFramework } from './getCurrentFramework.ts'; import { _, invokeCallbacks, onConsentChange } from './onConsentChange.ts'; import customVendorConsents from './tcfv2/__fixtures__/api.getCustomVendorConsents.json'; @@ -21,13 +21,13 @@ it('throws an error if no framework is present', () => { ); }); -describe('under CCPA', () => { +describe('under USNAT', () => { beforeEach(() => { window.__gpp = jest.fn((command, callback) => { if (command === 'ping') callback(gppData, true); }); - setCurrentFramework('ccpa'); + setCurrentFramework('usnat'); }); it('invokes callbacks correctly', async () => { diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts index 6fa9ed369..cdf4eca40 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts @@ -1,11 +1,11 @@ import { getConsentState as getAUSConsentState } from './aus/getConsentState'; -import { getConsentState as getCCPAConsentState } from './ccpa/getConsentState'; +import { getConsentState as getCCPAConsentState } from './usnat/getConsentState'; import { getCurrentFramework } from './getCurrentFramework'; import { getGpcSignal } from './lib/signals'; import { getConsentState as getTCFv2ConsentState } from './tcfv2/getConsentState'; import type { CallbackQueueItem, ConsentState, OnConsentChange } from './types'; import type { AUSConsentState } from './types/aus'; -import type { CCPAConsentState } from './types/ccpa'; +import type { CCPAConsentState } from './types/usnat'; import type { TCFv2ConsentState } from './types/tcfv2'; interface ConsentStateBasic { diff --git a/libs/@guardian/libs/src/consent-management-platform/types/index.ts b/libs/@guardian/libs/src/consent-management-platform/types/index.ts index bcf10227a..0e75ea106 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/index.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/index.ts @@ -1,7 +1,7 @@ import type { CountryCode } from '../../countries/@types/CountryCode'; import type { VendorName } from '../vendors'; import type { AUSConsentState } from './aus'; -import type { CCPAConsentState } from './ccpa'; +import type { USNATConsentState } from './usnat'; import type { TCFv2ConsentState } from './tcfv2'; export type ConsentFramework = 'tcfv2' | 'ccpa' | 'aus' | 'usnat'; @@ -34,7 +34,7 @@ export type GetConsentFor = ( export interface ConsentState { tcfv2?: TCFv2ConsentState; - ccpa?: CCPAConsentState; + ccpa?: USNATConsentState; // TODO: Should we change to `usa`? aus?: AUSConsentState; gpcSignal?: boolean; canTarget: boolean; diff --git a/libs/@guardian/libs/src/consent-management-platform/types/ccpa.ts b/libs/@guardian/libs/src/consent-management-platform/types/usnat.ts similarity index 89% rename from libs/@guardian/libs/src/consent-management-platform/types/ccpa.ts rename to libs/@guardian/libs/src/consent-management-platform/types/usnat.ts index 7e3fe89d5..a6c619bb1 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/ccpa.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/usnat.ts @@ -1,4 +1,4 @@ -export interface CCPAConsentState { +export interface USNATConsentState { doNotSell: boolean; } diff --git a/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts b/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts index 123c70f0b..9353f3f90 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts @@ -3,7 +3,7 @@ import type { Property } from '../lib/property'; import type { EndPoint } from '../lib/sourcepointConfig'; import type { onConsent } from '../onConsent'; import type { onConsentChange } from '../onConsentChange'; -import type { CCPAData, GPPData } from './ccpa'; +import type { CCPAData, GPPData } from './usnat'; import type { TCData } from './tcfv2/TCData'; import type { CMP, ConsentFramework, PubData } from '.'; diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.success.json b/libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.canSell.json similarity index 100% rename from libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.success.json rename to libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.canSell.json diff --git a/libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.doNotSell.json b/libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.doNotSell.json new file mode 100644 index 000000000..744689b40 --- /dev/null +++ b/libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.doNotSell.json @@ -0,0 +1,11 @@ +{ + "applicableSections": [7], + "gppString": "DBABLA~BEAgAAAAAgA.QA", + "gppVersion": "1.1", + "parsedSections": { + "usnatv1": { + "Version": 1, + "SaleOptOut": 1 + } + } +} diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.fail.json b/libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.fail.json similarity index 100% rename from libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getGPPData.fail.json rename to libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getGPPData.fail.json diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getUSPData.json b/libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getUSPData.json similarity index 100% rename from libs/@guardian/libs/src/consent-management-platform/ccpa/__fixtures__/api.getUSPData.json rename to libs/@guardian/libs/src/consent-management-platform/usnat/__fixtures__/api.getUSPData.json diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.test.js b/libs/@guardian/libs/src/consent-management-platform/usnat/api.test.js similarity index 87% rename from libs/@guardian/libs/src/consent-management-platform/ccpa/api.test.js rename to libs/@guardian/libs/src/consent-management-platform/usnat/api.test.js index 80c9ea29f..faf71682c 100644 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/usnat/api.test.js @@ -1,4 +1,4 @@ -import { getGPPData } from './api.ts'; +import { getGPPData } from './api.js'; it('calls the correct IAB api with the correct methods', async () => { expect(getGPPData()).rejects.toThrow(); diff --git a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.ts b/libs/@guardian/libs/src/consent-management-platform/usnat/api.ts similarity index 90% rename from libs/@guardian/libs/src/consent-management-platform/ccpa/api.ts rename to libs/@guardian/libs/src/consent-management-platform/usnat/api.ts index 6f1a18995..1526f1f3f 100644 --- a/libs/@guardian/libs/src/consent-management-platform/ccpa/api.ts +++ b/libs/@guardian/libs/src/consent-management-platform/usnat/api.ts @@ -1,4 +1,4 @@ -import type { GPPData } from '../types/ccpa'; +import type { GPPData } from '../types/usnat'; type Command = 'ping'; diff --git a/libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.test.js b/libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.test.js new file mode 100644 index 000000000..c70940161 --- /dev/null +++ b/libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.test.js @@ -0,0 +1,37 @@ +import gppDataCanSell from './__fixtures__/api.getGPPData.canSell.json'; +import gppDataDoNotSell from './__fixtures__/api.getGPPData.doNotSell.json'; +import gppDataFail from './__fixtures__/api.getGPPData.fail.json'; +import { getGPPData } from './api'; +import { getConsentState } from './getConsentState'; + +jest.mock('./api'); +// getGPPData.mockResolvedValue(gppDataSuccess); + +describe('getConsentState', () => { + it('gets the gpp consent state correctly - doNotSell is false', async () => { + getGPPData.mockResolvedValue(gppDataCanSell); + + const { doNotSell } = await getConsentState(); + expect(getGPPData).toHaveBeenCalledTimes(1); + + expect(doNotSell).toBe(false); + }); + + it('gets the gpp consent state correctly - doNotSell is true', async () => { + getGPPData.mockResolvedValue(gppDataDoNotSell); + + const { doNotSell } = await getConsentState(); + + expect(getGPPData).toHaveBeenCalledTimes(1); + expect(doNotSell).toBe(true); + }); + + it('gets the gpp consent state correctly if it fails - doNotSell is true', async () => { + getGPPData.mockResolvedValue(gppDataFail); + + const { doNotSell } = await getConsentState(); + + expect(getGPPData).toHaveBeenCalledTimes(1); + expect(doNotSell).toBe(true); + }); +}); diff --git a/libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.ts b/libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.ts new file mode 100644 index 000000000..b85bd0855 --- /dev/null +++ b/libs/@guardian/libs/src/consent-management-platform/usnat/getConsentState.ts @@ -0,0 +1,12 @@ +import type { USNATConsentState } from '../types/usnat'; +import { getGPPData } from './api'; + +// get the current consent state using the official IAB method +export const getConsentState: () => Promise = async () => { + const gppData = await getGPPData(); + + return { + // https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/blob/main/Sections/US-National/IAB%20Privacy%E2%80%99s%20National%20Privacy%20Technical%20Specification.md + doNotSell: gppData.parsedSections.usnatv1?.SaleOptOut !== 2, + }; +}; From c06fcc86d2696998d0d5ba4c543085883c38f155 Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:48:35 +0100 Subject: [PATCH 07/52] Update ccpa to usnat --- .../onConsent.test.ts | 6 +++--- .../onConsentChange.enhanced.test.ts | 18 +++++++++--------- .../onConsentChange.ts | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts b/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts index dc00f1448..cce842f5a 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsent.test.ts @@ -2,8 +2,8 @@ import { onConsent } from './onConsent'; import { onConsentChange } from './onConsentChange'; import type { ConsentState, OnConsentChangeCallback } from './types'; import type { AUSConsentState } from './types/aus'; -import type { CCPAConsentState } from './types/usnat'; import type { TCFv2ConsentState } from './types/tcfv2'; +import type { USNATConsentState } from './types/usnat'; jest.mock('./onConsentChange'); @@ -18,7 +18,7 @@ const tcfv2ConsentState: TCFv2ConsentState = { tcString: 'YAAA', }; -const ccpaConsentState: CCPAConsentState = { +const usnatConsentState: USNATConsentState = { doNotSell: false, }; @@ -44,7 +44,7 @@ describe('onConsent returns a promise that resolves the initial consent state', }); test('ccpa', async () => { const consentState: ConsentState = { - ccpa: ccpaConsentState, + ccpa: usnatConsentState, canTarget: true, framework: 'ccpa', }; diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts index da598775a..16a541511 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts @@ -5,8 +5,8 @@ import { _ } from './onConsentChange'; import { getConsentState as getTCFv2ConsentState } from './tcfv2/getConsentState'; import type { ConsentFramework, ConsentState } from './types'; import type { AUSConsentState } from './types/aus'; -import type { CCPAConsentState } from './types/usnat'; import type { TCFv2ConsentState } from './types/tcfv2'; +import type { USNATConsentState } from './types/usnat'; jest.mock('./tcfv2/getConsentState'); jest.mock('./ccpa/getConsentState'); @@ -23,7 +23,7 @@ const tcfv2ConsentState: TCFv2ConsentState = { tcString: 'YAAA', }; -const ccpaConsentState: CCPAConsentState = { +const usnatConsentState: USNATConsentState = { doNotSell: false, }; @@ -32,8 +32,8 @@ const ausConsentState: AUSConsentState = { }; const setAPI = (framework: ConsentFramework | null) => { - if (framework === 'ccpa') { - setCurrentFramework('ccpa'); + if (framework === 'usnat') { + setCurrentFramework('usnat'); return; } else if (framework === 'aus') { setCurrentFramework('aus'); @@ -83,11 +83,11 @@ describe('onConsentChange enhances basic consent state', () => { }); test('ccpa can target', async () => { (getCCPAConsentState as jest.Mock).mockImplementation(() => - Promise.resolve(ccpaConsentState), + Promise.resolve(usnatConsentState), ); setAPI('ccpa'); const expectedConsentState: ConsentState = { - ccpa: ccpaConsentState, + ccpa: usnatConsentState, canTarget: true, framework: 'ccpa', }; @@ -96,7 +96,7 @@ describe('onConsentChange enhances basic consent state', () => { }); test('ccpa can NOT target', async () => { (getCCPAConsentState as jest.Mock).mockImplementation(() => - Promise.resolve({ doNotSell: true }), + Promise.resolve({ doNotSell: true }), ); setAPI('ccpa'); const expectedConsentState: ConsentState = { @@ -146,11 +146,11 @@ describe('onConsentChange enhances basic consent state', () => { test('notices a GPC signal', async () => { setGpc(true); (getCCPAConsentState as jest.Mock).mockImplementation(() => - Promise.resolve(ccpaConsentState), + Promise.resolve(usnatConsentState), ); setAPI('ccpa'); const expectedConsentState: ConsentState = { - ccpa: ccpaConsentState, + ccpa: usnatConsentState, canTarget: true, framework: 'ccpa', gpcSignal: true, diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts index cdf4eca40..19e34971d 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts @@ -5,12 +5,12 @@ import { getGpcSignal } from './lib/signals'; import { getConsentState as getTCFv2ConsentState } from './tcfv2/getConsentState'; import type { CallbackQueueItem, ConsentState, OnConsentChange } from './types'; import type { AUSConsentState } from './types/aus'; -import type { CCPAConsentState } from './types/usnat'; import type { TCFv2ConsentState } from './types/tcfv2'; +import type { USNATConsentState } from './types/usnat'; interface ConsentStateBasic { tcfv2?: TCFv2ConsentState; - ccpa?: CCPAConsentState; + ccpa?: USNATConsentState; aus?: AUSConsentState; } @@ -88,7 +88,7 @@ const getConsentState: () => Promise = async () => { switch (getCurrentFramework()) { case 'aus': return enhanceConsentState({ aus: await getAUSConsentState() }); - case 'ccpa': + case 'usnat': return enhanceConsentState({ ccpa: await getCCPAConsentState() }); case 'tcfv2': return enhanceConsentState({ tcfv2: await getTCFv2ConsentState() }); From 6a73120dd2a60f06e8496c3078fa79809970fc07 Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:17:58 +0100 Subject: [PATCH 08/52] Updating from ccpa to usnat --- .../getFramework.test.js | 4 ++-- .../consent-management-platform/index.test.ts | 2 +- .../onConsentChange.enhanced.test.ts | 24 +++++++++---------- .../onConsentChange.test.js | 2 +- .../onConsentChange.ts | 4 ++-- .../sourcepoint.test.js | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libs/@guardian/libs/src/consent-management-platform/getFramework.test.js b/libs/@guardian/libs/src/consent-management-platform/getFramework.test.js index b7f82af01..0f2c807d0 100644 --- a/libs/@guardian/libs/src/consent-management-platform/getFramework.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/getFramework.test.js @@ -2,7 +2,7 @@ import { getFramework } from './getFramework.ts'; /* cSpell:disable */ const countries = { - ccpa: [['UnitedStates', 'US']], + usnat: [['UnitedStates', 'US']], aus: [['Australia', 'AU']], tcfv2: [ ['Afghanistan', 'AF'], @@ -259,7 +259,7 @@ const countries = { describe('Match countries and framework', () => { describe.each([ ['AUS', 'aus'], - ['CCPA', 'ccpa'], + ['USNAT', 'usnat'], ['TCFv2', 'tcfv2'], ])('%s', (name, framework) => { it.each(countries[framework])( diff --git a/libs/@guardian/libs/src/consent-management-platform/index.test.ts b/libs/@guardian/libs/src/consent-management-platform/index.test.ts index 77b5d6251..512c0b437 100644 --- a/libs/@guardian/libs/src/consent-management-platform/index.test.ts +++ b/libs/@guardian/libs/src/consent-management-platform/index.test.ts @@ -88,7 +88,7 @@ describe('hotfix cmp.init', () => { it.each([ ['GB', 'tcfv2'], ['AU', 'aus'], - ['US', 'ccpa'], + ['US', 'usnat'], ['YT', 'tcfv2'], ['FR', 'tcfv2'], ['CA', 'tcfv2'], diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts index 16a541511..ed540557f 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.enhanced.test.ts @@ -1,5 +1,4 @@ import { getConsentState as getAUSConsentState } from './aus/getConsentState'; -import { getConsentState as getCCPAConsentState } from './usnat/getConsentState'; import { setCurrentFramework, unsetFramework } from './getCurrentFramework'; import { _ } from './onConsentChange'; import { getConsentState as getTCFv2ConsentState } from './tcfv2/getConsentState'; @@ -7,9 +6,10 @@ import type { ConsentFramework, ConsentState } from './types'; import type { AUSConsentState } from './types/aus'; import type { TCFv2ConsentState } from './types/tcfv2'; import type { USNATConsentState } from './types/usnat'; +import { getConsentState as getUSNATConsentState } from './usnat/getConsentState'; jest.mock('./tcfv2/getConsentState'); -jest.mock('./ccpa/getConsentState'); +jest.mock('./usnat/getConsentState'); jest.mock('./aus/getConsentState'); const tcfv2ConsentState: TCFv2ConsentState = { @@ -81,28 +81,28 @@ describe('onConsentChange enhances basic consent state', () => { const consentState = await _.getConsentState(); expect(consentState).toEqual(expectedConsentState); }); - test('ccpa can target', async () => { - (getCCPAConsentState as jest.Mock).mockImplementation(() => + test('usnat can target', async () => { + (getUSNATConsentState as jest.Mock).mockImplementation(() => Promise.resolve(usnatConsentState), ); - setAPI('ccpa'); + setAPI('usnat'); const expectedConsentState: ConsentState = { ccpa: usnatConsentState, canTarget: true, - framework: 'ccpa', + framework: 'usnat', }; const consentState = await _.getConsentState(); expect(consentState).toEqual(expectedConsentState); }); test('ccpa can NOT target', async () => { - (getCCPAConsentState as jest.Mock).mockImplementation(() => + (getUSNATConsentState as jest.Mock).mockImplementation(() => Promise.resolve({ doNotSell: true }), ); - setAPI('ccpa'); + setAPI('usnat'); const expectedConsentState: ConsentState = { ccpa: { doNotSell: true }, canTarget: false, - framework: 'ccpa', + framework: 'usnat', }; const consentState = await _.getConsentState(); expect(consentState).toEqual(expectedConsentState); @@ -145,14 +145,14 @@ describe('onConsentChange enhances basic consent state', () => { }); test('notices a GPC signal', async () => { setGpc(true); - (getCCPAConsentState as jest.Mock).mockImplementation(() => + (getUSNATConsentState as jest.Mock).mockImplementation(() => Promise.resolve(usnatConsentState), ); - setAPI('ccpa'); + setAPI('usnat'); const expectedConsentState: ConsentState = { ccpa: usnatConsentState, canTarget: true, - framework: 'ccpa', + framework: 'usnat', gpcSignal: true, }; diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js index 9da438778..592e9da77 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.test.js @@ -1,9 +1,9 @@ import ausData from './aus/__fixtures__/api.getUSPData.json'; -import gppData from './usnat/__fixtures__/api.getGPPData.success.json'; import { setCurrentFramework } from './getCurrentFramework.ts'; import { _, invokeCallbacks, onConsentChange } from './onConsentChange.ts'; import customVendorConsents from './tcfv2/__fixtures__/api.getCustomVendorConsents.json'; import tcData from './tcfv2/__fixtures__/api.getTCData.json'; +import gppData from './usnat/__fixtures__/api.getGPPData.canSell.json'; const resolveAllPromises = () => new Promise((resolve) => process.nextTick(resolve)); diff --git a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts index 19e34971d..e91bba7ad 100644 --- a/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts +++ b/libs/@guardian/libs/src/consent-management-platform/onConsentChange.ts @@ -1,5 +1,4 @@ import { getConsentState as getAUSConsentState } from './aus/getConsentState'; -import { getConsentState as getCCPAConsentState } from './usnat/getConsentState'; import { getCurrentFramework } from './getCurrentFramework'; import { getGpcSignal } from './lib/signals'; import { getConsentState as getTCFv2ConsentState } from './tcfv2/getConsentState'; @@ -7,6 +6,7 @@ import type { CallbackQueueItem, ConsentState, OnConsentChange } from './types'; import type { AUSConsentState } from './types/aus'; import type { TCFv2ConsentState } from './types/tcfv2'; import type { USNATConsentState } from './types/usnat'; +import { getConsentState as getCCPAConsentState } from './usnat/getConsentState'; interface ConsentStateBasic { tcfv2?: TCFv2ConsentState; @@ -65,7 +65,7 @@ const enhanceConsentState = (consentState: ConsentStateBasic): ConsentState => { return { ...consentState, canTarget: !consentState.ccpa.doNotSell, - framework: 'ccpa', + framework: 'usnat', gpcSignal, }; } else if (consentState.aus) { diff --git a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js index ecb21b46f..34bdc90f3 100644 --- a/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js +++ b/libs/@guardian/libs/src/consent-management-platform/sourcepoint.test.js @@ -42,7 +42,7 @@ describe('Sourcepoint unified', () => { expect(window.__tcfapi).toBeDefined(); expect(window.__uspapi).toBeUndefined(); expect(window.__gpp).toBeUndefined(); - } else if (framework == 'ccpa') { + } else if (framework == 'usnat') { expect(window._sp_.config.usnat.includeUspApi).toBeTruthy(); expect(window._sp_.config.usnat.transitionCCPAAuth).toBeTruthy(); expect(window._sp_.config.usnat.targetingParams.framework).toEqual( From 460a4ad55d53c01509abd57dd0edfa85089d1785 Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:24:50 +0100 Subject: [PATCH 09/52] Update lint --- .../libs/src/consent-management-platform/aus/api.ts | 2 +- .../libs/src/consent-management-platform/types/aus.ts | 5 +++++ .../libs/src/consent-management-platform/types/index.ts | 2 +- .../libs/src/consent-management-platform/types/usnat.ts | 5 ----- .../libs/src/consent-management-platform/types/window.d.ts | 3 ++- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/libs/@guardian/libs/src/consent-management-platform/aus/api.ts b/libs/@guardian/libs/src/consent-management-platform/aus/api.ts index e650f7414..efa0ee142 100644 --- a/libs/@guardian/libs/src/consent-management-platform/aus/api.ts +++ b/libs/@guardian/libs/src/consent-management-platform/aus/api.ts @@ -1,4 +1,4 @@ -import type { CCPAData } from '../types/usnat'; +import type { CCPAData } from '../types/aus'; type Command = 'getUSPData'; diff --git a/libs/@guardian/libs/src/consent-management-platform/types/aus.ts b/libs/@guardian/libs/src/consent-management-platform/types/aus.ts index d1e3a5c36..7ffd846c4 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/aus.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/aus.ts @@ -1,3 +1,8 @@ export interface AUSConsentState { personalisedAdvertising: boolean; } + +export interface CCPAData { + version: number; + uspString: string; +} diff --git a/libs/@guardian/libs/src/consent-management-platform/types/index.ts b/libs/@guardian/libs/src/consent-management-platform/types/index.ts index 0e75ea106..d9ffe2639 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/index.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/index.ts @@ -1,8 +1,8 @@ import type { CountryCode } from '../../countries/@types/CountryCode'; import type { VendorName } from '../vendors'; import type { AUSConsentState } from './aus'; -import type { USNATConsentState } from './usnat'; import type { TCFv2ConsentState } from './tcfv2'; +import type { USNATConsentState } from './usnat'; export type ConsentFramework = 'tcfv2' | 'ccpa' | 'aus' | 'usnat'; diff --git a/libs/@guardian/libs/src/consent-management-platform/types/usnat.ts b/libs/@guardian/libs/src/consent-management-platform/types/usnat.ts index a6c619bb1..bd080f538 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/usnat.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/usnat.ts @@ -2,11 +2,6 @@ export interface USNATConsentState { doNotSell: boolean; } -export interface CCPAData { - version: number; - uspString: string; -} - interface GppParsedSections { usnatv1?: { Version: number; diff --git a/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts b/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts index 9353f3f90..c703dad06 100644 --- a/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts +++ b/libs/@guardian/libs/src/consent-management-platform/types/window.d.ts @@ -3,8 +3,9 @@ import type { Property } from '../lib/property'; import type { EndPoint } from '../lib/sourcepointConfig'; import type { onConsent } from '../onConsent'; import type { onConsentChange } from '../onConsentChange'; -import type { CCPAData, GPPData } from './usnat'; +import type { CCPAData } from './aus'; import type { TCData } from './tcfv2/TCData'; +import type { GPPData } from './usnat'; import type { CMP, ConsentFramework, PubData } from '.'; type OnMessageChoiceSelect = ( From 05dc5b9afc3533f90f308a9b2dd3fe46923a715f Mon Sep 17 00:00:00 2001 From: Akinsola Lawanson <106528085+akinsola-guardian@users.noreply.github.com> Date: Thu, 11 Apr 2024 11:53:25 +0100 Subject: [PATCH 10/52] Replace ccpa with usnat --- apps/github-pages/src/components/CmpTest.svelte | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/github-pages/src/components/CmpTest.svelte b/apps/github-pages/src/components/CmpTest.svelte index fae2baaab..53790ee12 100644 --- a/apps/github-pages/src/components/CmpTest.svelte +++ b/apps/github-pages/src/components/CmpTest.svelte @@ -7,8 +7,8 @@ case '#tcfv2': localStorage.setItem('framework', JSON.stringify('tcfv2')); break; - case '#ccpa': - localStorage.setItem('framework', JSON.stringify('ccpa')); + case '#usnat': + localStorage.setItem('framework', JSON.stringify('usnat')); break; case '#aus': localStorage.setItem('framework', JSON.stringify('aus')); @@ -81,7 +81,7 @@ country = 'GB'; break; - case 'ccpa': + case 'usnat': country = 'US'; break; @@ -113,15 +113,15 @@ /> in RoW:TCFv2 -