Skip to content

Commit

Permalink
refactor and wrap all exported storage from libs
Browse files Browse the repository at this point in the history
  • Loading branch information
vlkerag committed Dec 21, 2023
1 parent 3eff973 commit 3ba5a9a
Show file tree
Hide file tree
Showing 8 changed files with 492 additions and 256 deletions.
113 changes: 113 additions & 0 deletions src/cmpCookies.tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { onConsentChange } from './onConsentChange';
import type { Callback, ConsentState } from './types';
import type { TCFv2ConsentState } from './types/tcfv2';
import {cmpGetCookie, cmpSetCookie } from './cmpCookies';
import { getCookie as getCookie_, setCookie as setCookie_} from '@guardian/libs';

jest.mock('./onConsentChange');
jest.mock('@guardian/libs', () => ({
getCookie: jest.fn(),
setCookie: jest.fn(),
storage: {
local: {
get: jest.fn(),
set: jest.fn(),
},
session: {
get: jest.fn(),
set: jest.fn(),
},
}
}));

const tcfv2ConsentState: TCFv2ConsentState = {
consents: { 1: true },
eventStatus: 'tcloaded',
vendorConsents: {
['5efefe25b8e05c06542b2a77']: true,
},
addtlConsent: 'xyz',
gdprApplies: true,
tcString: 'YAAA',
};

const tcfv2ConsentStateNoConsent: TCFv2ConsentState = {
consents: { 1: false },
eventStatus: 'tcloaded',
vendorConsents: {},
addtlConsent: 'xyz',
gdprApplies: true,
tcString: 'YAAA',
};

const mockOnConsentChange = (consentState: ConsentState) =>
(onConsentChange as jest.Mock).mockImplementation((cb: Callback) => cb(consentState));

describe('cookies return the expected consent', () => {
let mockContains:any;

beforeEach(() => {
mockContains = 'someTestData';

(getCookie_ as jest.Mock).mockImplementation(({name }: {
name: string;
}) => {
if (name === 'gu.mock') {return mockContains}
else {return(null)}
});

(setCookie_ as jest.Mock).mockImplementation(({ name, value }: {
name: string;
value: string;
}) => {
if (name === 'gu.mock') {mockContains = value;}
});
});

test('Targeted advertising get cookie returns null when canTarget is false', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentState,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValue = await cmpGetCookie({useCase: 'Targeted advertising', name: 'gu.mock'});
expect(cookieValue).toEqual(null);
});
test('Targeted advertising can set and get cookies when canTarget is true', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentState,
canTarget: true,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValueDefault = await cmpGetCookie({useCase: 'Targeted advertising', name: 'gu.mock'});
expect(cookieValueDefault).toEqual('someTestData');
await cmpSetCookie({useCase: 'Essential', name: 'gu.mock', value: 'testdataAd'});
const cookieValue = await cmpGetCookie({useCase: 'Targeted advertising', name: 'gu.mock'});
expect(cookieValue).toEqual('testdataAd');
});
test('Essential can set and get cookies when no consents', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentStateNoConsent,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValueDefault = await cmpGetCookie({useCase: 'Essential', name:'gu.mock'});
expect(cookieValueDefault).toEqual('someTestData');
await cmpSetCookie({useCase: 'Essential', name: 'gu.mock', value: 'testdata'});
const cookieValue = await cmpGetCookie({useCase: 'Essential', name: 'gu.mock'});
expect(cookieValue).toEqual('testdata');
});
test('get null if cookie does not exist', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentStateNoConsent,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValue = await cmpGetCookie({useCase: 'Essential', name: 'gu.does_not_exist'});
expect(cookieValue).toEqual(null);
});
});
62 changes: 62 additions & 0 deletions src/cmpCookies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { getCookie, setCookie, setSessionCookie } from '@guardian/libs';
import type { ConsentUseCases } from './types/consentUseCases';
import { hasConsentForUseCase } from './hasConsentForUseCase';

//TODO: Write wrappers for the other cookie functions in @guardian/libs

export const cmpGetCookie = async({ useCase, name, shouldMemoize, }: {
useCase: ConsentUseCases,
name: string;
shouldMemoize?: boolean | undefined;
}): Promise<string | null> =>
{
console.log('in cmpGetCookie');

if(await hasConsentForUseCase(useCase))
{
return getCookie({name: name, shouldMemoize: shouldMemoize})
}
else
{
console.error('cmp', `Cannot get cookie ${name} due to missing consent for use-case ${useCase}`)
return(null)
}
};

export const cmpSetCookie = async ({ useCase, name, value, daysToLive, isCrossSubdomain, }: {
useCase: ConsentUseCases,
name: string;
value: string;
daysToLive?: number | undefined;
isCrossSubdomain?: boolean | undefined;
}): Promise<void> =>
{
console.log('in cmpSetCookie');

if(await hasConsentForUseCase(useCase))
{
setCookie({name:name, value:value, daysToLive:daysToLive, isCrossSubdomain:isCrossSubdomain})
}
else
{
console.error('cmp', `Cannot set cookie ${name} due to missing consent for use-case ${useCase}`)
}
};

export const cmpSetSessionCookie = async ({ useCase, name, value }: {
useCase: ConsentUseCases,
name: string;
value: string;
}): Promise<void> =>
{
console.log('in cmpSetSessionCookie');

if(await hasConsentForUseCase(useCase))
{
setSessionCookie({name:name, value:value})
}
else
{
console.error('cmp', `Cannot set cookie ${name} due to missing consent for use-case ${useCase}`)
}
};
142 changes: 20 additions & 122 deletions src/cmpStorage.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { onConsentChange } from './onConsentChange';
import type { Callback, ConsentState } from './types';
import type { TCFv2ConsentState } from './types/tcfv2';
import {cmpGetLocalStorageItem, cmpSetLocalStorageItem, cmpGetSessionStorageItem, cmpSetSessionStorageItem, cmpGetCookie, cmpSetCookie, hasConsentForUseCase } from './cmpStorage';
import { getCookie as getCookie_, setCookie as setCookie_, storage as storageStub} from '@guardian/libs';
import {storage} from './cmpStorage';
import { storage as storageStub} from '@guardian/libs';

//TODO: add tests for all use-cases and all other storage functions

jest.mock('./onConsentChange');
jest.mock('@guardian/libs', () => ({
Expand Down Expand Up @@ -43,40 +45,6 @@ const tcfv2ConsentStateNoConsent: TCFv2ConsentState = {
const mockOnConsentChange = (consentState: ConsentState) =>
(onConsentChange as jest.Mock).mockImplementation((cb: Callback) => cb(consentState));

describe('cmpStorage.hasConsentForUseCase returns the expected consent', () => {
test('Targeted advertising has consent when canTarget is true', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentState,
canTarget: true,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const hasConsent = await hasConsentForUseCase('Targeted advertising');
expect(hasConsent).toEqual(true);
});
test('Targeted advertising has no consent when canTarget is false', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentState,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const hasConsent = await hasConsentForUseCase('Targeted advertising');
expect(hasConsent).toEqual(false);
});
test('Essential has consent even when ConsentState has no consents', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentStateNoConsent,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const hasConsent = await hasConsentForUseCase('Essential');
expect(hasConsent).toEqual(true);
});
});


describe('local storage returns the expected consent', () => {
let mockContains:any;

Expand All @@ -100,7 +68,7 @@ describe('local storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const localStorageValue = await cmpGetLocalStorageItem('Targeted advertising', 'gu.mock');
const localStorageValue = await storage.local.get('Targeted advertising', 'gu.mock');
expect(localStorageValue).toEqual(null);
});
test('Targeted advertising can set and get local storage value when canTarget is true', async () => {
Expand All @@ -110,10 +78,10 @@ describe('local storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const localStorageValueDefault = await cmpGetLocalStorageItem('Targeted advertising', 'gu.mock');
const localStorageValueDefault = await storage.local.get('Targeted advertising', 'gu.mock');
expect(localStorageValueDefault).toEqual('someTestData');
await cmpSetLocalStorageItem('Essential', 'gu.mock', 'testdataAd');
const localStorageValue = await cmpGetLocalStorageItem('Targeted advertising', 'gu.mock');
await storage.local.set('Essential', 'gu.mock', 'testdataAd');
const localStorageValue = await storage.local.get('Targeted advertising', 'gu.mock');
expect(localStorageValue).toEqual('testdataAd');
});
test('Essential can set and get local storage when no consents', async () => {
Expand All @@ -123,10 +91,10 @@ describe('local storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const localStorageValueDefault = await cmpGetLocalStorageItem('Essential', 'gu.mock');
const localStorageValueDefault = await storage.local.get('Essential', 'gu.mock');
expect(localStorageValueDefault).toEqual('someTestData');
await cmpSetLocalStorageItem('Essential', 'gu.mock', 'testdata');
const localStorageValue = await cmpGetLocalStorageItem('Essential', 'gu.mock');
await storage.local.set('Essential', 'gu.mock', 'testdata');
const localStorageValue = await storage.local.get('Essential', 'gu.mock');
expect(localStorageValue).toEqual('testdata');
});
test('get null if local storage item does not exist', async () => {
Expand All @@ -136,7 +104,7 @@ describe('local storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const localStorageValue = await cmpGetLocalStorageItem('Essential', 'gu.does_not_exist');
const localStorageValue = await storage.local.get('Essential', 'gu.does_not_exist');
expect(localStorageValue).toEqual(null);
});
});
Expand Down Expand Up @@ -165,7 +133,7 @@ describe('session storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const sessionStorageValue = await cmpGetSessionStorageItem('Targeted advertising', 'gu.mock');
const sessionStorageValue = await storage.session.get('Targeted advertising', 'gu.mock');
expect(sessionStorageValue).toEqual(null);
});
test('Targeted advertising can set and get session storage value when canTarget is true', async () => {
Expand All @@ -175,10 +143,10 @@ describe('session storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const sessionStorageValueDefault = await cmpGetSessionStorageItem('Targeted advertising', 'gu.mock');
const sessionStorageValueDefault = await storage.session.get('Targeted advertising', 'gu.mock');
expect(sessionStorageValueDefault).toEqual('someTestData');
await cmpSetSessionStorageItem('Essential', 'gu.mock', 'testdataAd');
const sessionStorageValue = await cmpGetSessionStorageItem('Targeted advertising', 'gu.mock');
await storage.session.set('Essential', 'gu.mock', 'testdataAd');
const sessionStorageValue = await storage.session.get('Targeted advertising', 'gu.mock');
expect(sessionStorageValue).toEqual('testdataAd');
});
test('Essential can set and get session storage when no consents', async () => {
Expand All @@ -188,10 +156,10 @@ describe('session storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const sessionStorageValueDefault = await cmpGetSessionStorageItem('Essential', 'gu.mock');
const sessionStorageValueDefault = await storage.session.get('Essential', 'gu.mock');
expect(sessionStorageValueDefault).toEqual('someTestData');
await cmpSetSessionStorageItem('Essential', 'gu.mock', 'testdata');
const sessionStorageValue = await cmpGetSessionStorageItem('Essential', 'gu.mock');
await storage.session.set('Essential', 'gu.mock', 'testdata');
const sessionStorageValue = await storage.session.get('Essential', 'gu.mock');
expect(sessionStorageValue).toEqual('testdata');
});
test('get null if session storage item does not exist', async () => {
Expand All @@ -201,77 +169,7 @@ describe('session storage returns the expected consent', () => {
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const sessionStorageValue = await cmpGetSessionStorageItem('Essential', 'gu.does_not_exist');
const sessionStorageValue = await storage.session.get('Essential', 'gu.does_not_exist');
expect(sessionStorageValue).toEqual(null);
});
});


describe('cookies return the expected consent', () => {
let mockContains:any;

beforeEach(() => {
mockContains = 'someTestData';

(getCookie_ as jest.Mock).mockImplementation(({name }: {
name: string;
}) => {
if (name === 'gu.mock') {return mockContains}
else {return(null)}
});

(setCookie_ as jest.Mock).mockImplementation(({ name, value }: {
name: string;
value: string;
}) => {
if (name === 'gu.mock') {mockContains = value;}
});
});

test('Targeted advertising get cookie returns null when canTarget is false', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentState,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValue = await cmpGetCookie({useCase: 'Targeted advertising', name: 'gu.mock'});
expect(cookieValue).toEqual(null);
});
test('Targeted advertising can set and get cookies when canTarget is true', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentState,
canTarget: true,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValueDefault = await cmpGetCookie({useCase: 'Targeted advertising', name: 'gu.mock'});
expect(cookieValueDefault).toEqual('someTestData');
await cmpSetCookie({useCase: 'Essential', name: 'gu.mock', value: 'testdataAd'});
const cookieValue = await cmpGetCookie({useCase: 'Targeted advertising', name: 'gu.mock'});
expect(cookieValue).toEqual('testdataAd');
});
test('Essential can set and get cookies when no consents', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentStateNoConsent,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValueDefault = await cmpGetCookie({useCase: 'Essential', name:'gu.mock'});
expect(cookieValueDefault).toEqual('someTestData');
await cmpSetCookie({useCase: 'Essential', name: 'gu.mock', value: 'testdata'});
const cookieValue = await cmpGetCookie({useCase: 'Essential', name: 'gu.mock'});
expect(cookieValue).toEqual('testdata');
});
test('get null if cookie does not exist', async () => {
const consentState: ConsentState = {
tcfv2: tcfv2ConsentStateNoConsent,
canTarget: false,
framework: 'tcfv2',
};
mockOnConsentChange(consentState);
const cookieValue = await cmpGetCookie({useCase: 'Essential', name: 'gu.does_not_exist'});
expect(cookieValue).toEqual(null);
});
});

1 comment on commit 3ba5a9a

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage report

St.
Category Percentage Covered / Total
🟢 Statements 82.42% 272/330
🟡 Branches 67.76% 103/152
🟢 Functions 82.14% 69/84
🟢 Lines 81.93% 263/321

Test suite run success

339 tests passing in 18 suites.

Report generated by 🧪jest coverage report action from 3ba5a9a

Please sign in to comment.