Skip to content

Commit

Permalink
parrableIdSystem: Consume US Privacy consent data (#5197)
Browse files Browse the repository at this point in the history
* Add unit coverage for parrableIdSystem getId callback

* PBID-14: Pass uspString to Parrable as us_privacy query parameter

* PBID-14: Simplify parrableIdSystem us_privacy test

* PBID-14: Only send us_privacy to Parrable when a value exists

* Remove path check from parrableIdSystem url test

* Add missing extension to mock xhr import
  • Loading branch information
icflournoy authored May 11, 2020
1 parent 2dc1125 commit c867e7d
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 13 deletions.
12 changes: 9 additions & 3 deletions modules/parrableIdSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as utils from '../src/utils.js'
import { ajax } from '../src/ajax.js';
import { submodule } from '../src/hook.js';
import { getRefererInfo } from '../src/refererDetection.js';
import { uspDataHandler } from '../src/adapterManager.js';

const PARRABLE_URL = 'https://h.parrable.com/prebid';

Expand All @@ -24,10 +25,11 @@ function isValidConfig(configParams) {
return true;
}

function fetchId(configParams, consentData, currentStoredId) {
function fetchId(configParams, currentStoredId) {
if (!isValidConfig(configParams)) return;

const refererInfo = getRefererInfo();
const uspString = uspDataHandler.getConsentData();

const data = {
eid: currentStoredId || null,
Expand All @@ -40,6 +42,10 @@ function fetchId(configParams, consentData, currentStoredId) {
_rand: Math.random()
};

if (uspString) {
searchParams.us_privacy = uspString;
}

const options = {
method: 'GET',
withCredentials: true
Expand Down Expand Up @@ -88,8 +94,8 @@ export const parrableIdSubmodule = {
* @param {ConsentData} [consentData]
* @returns {function(callback:function)}
*/
getId(configParams, consentData, currentStoredId) {
return fetchId(configParams, consentData, currentStoredId);
getId(configParams, gdprConsentData, currentStoredId) {
return fetchId(configParams, currentStoredId);
}
};

Expand Down
83 changes: 73 additions & 10 deletions test/spec/modules/parrableIdSystem_spec.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { expect } from 'chai';
import {config} from 'src/config.js';
import { config } from 'src/config.js';
import * as utils from 'src/utils.js';
import { newStorageManager } from 'src/storageManager.js';
import { getRefererInfo } from 'src/refererDetection.js';
import { uspDataHandler } from 'src/adapterManager.js';
import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js';
import { parrableIdSubmodule } from 'modules/parrableIdSystem.js';
import { newStorageManager } from 'src/storageManager.js';
import { server } from 'test/mocks/xhr.js';

const storage = newStorageManager();

const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT';
const P_COOKIE_NAME = '_parrable_eid';
const P_COOKIE_VALUE = '01.1563917337.test-eid';
const P_COOKIE_EID = '01.1563917337.test-eid';
const P_XHR_EID = '01.1588030911.test-new-eid'
const P_CONFIG_MOCK = {
name: 'parrableId',
params: {
Expand All @@ -31,6 +35,7 @@ describe('Parrable ID System', function() {
}
}
}

function getAdUnitMock(code = 'adUnit-code') {
return {
code,
Expand All @@ -46,33 +51,91 @@ describe('Parrable ID System', function() {
};
}

describe('parrableIdSystem.getId()', function() {
let callbackSpy = sinon.spy();

beforeEach(function() {
callbackSpy.resetHistory();
});

it('returns a callback used to refresh the ID', function() {
let getIdResponse = parrableIdSubmodule.getId(
P_CONFIG_MOCK.params,
null,
P_COOKIE_EID
);
expect(getIdResponse.callback).to.be.a('function');
});

it('callback creates xhr to Parrable that synchronizes the ID', function() {
let getIdCallback = parrableIdSubmodule.getId(
P_CONFIG_MOCK.params,
null,
P_COOKIE_EID
).callback;

getIdCallback(callbackSpy);

let request = server.requests[0];
let queryParams = utils.parseQS(request.url.split('?')[1]);
let data = JSON.parse(atob(queryParams.data));

expect(request.url).to.contain('h.parrable.com');
expect(queryParams).to.not.have.property('us_privacy');
expect(data).to.deep.equal({
eid: P_COOKIE_EID,
trackers: P_CONFIG_MOCK.params.partner.split(','),
url: getRefererInfo().referer
});

server.requests[0].respond(200,
{ 'Content-Type': 'text/plain' },
JSON.stringify({ eid: P_XHR_EID })
);

expect(callbackSpy.calledWith(P_XHR_EID)).to.be.true;
});

it('passes the uspString to Parrable', function() {
let uspString = '1YNN';
uspDataHandler.setConsentData(uspString);
parrableIdSubmodule.getId(
P_CONFIG_MOCK.params,
null,
P_COOKIE_EID
).callback(callbackSpy);
expect(server.requests[0].url).to.contain('us_privacy=' + uspString);
});
});

describe('Parrable ID in Bid Request', function() {
let adUnits;

beforeEach(function() {
adUnits = [getAdUnitMock()];
});

it('should append parrableid to bid request', function(done) {
// simulate existing browser local storage values
storage.setCookie(
P_COOKIE_NAME,
P_COOKIE_VALUE,
P_COOKIE_EID,
(new Date(Date.now() + 5000).toUTCString())
);

setSubmoduleRegistry([parrableIdSubmodule]);
init(config);
config.setConfig(getConfigMock());
});

afterEach(function() {
storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE);
});

it('provides the parrableid in the bid request', function(done) {
requestBidsHook(function() {
adUnits.forEach(unit => {
unit.bids.forEach(bid => {
expect(bid).to.have.deep.nested.property('userId.parrableid');
expect(bid.userId.parrableid).to.equal(P_COOKIE_VALUE);
expect(bid.userId.parrableid).to.equal(P_COOKIE_EID);
});
});
storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE);
done();
}, { adUnits });
});
Expand Down

0 comments on commit c867e7d

Please sign in to comment.