Skip to content

Commit

Permalink
Zeotap ID+ submodule (#5640)
Browse files Browse the repository at this point in the history
* IDU-117 IDU-119 Add zeotap submodule

* IDU-117 IDU-119 Add tests for zeotapId+ module

* add zeotapId+ module spec

* Add IDP base64 decode logic

* remove unwanted file changes

* rename zeotapId+ to zeotapIdPlus

* add zeotapIdPlus submodule to submodules.json

* refactor code for requested changes: remove storage from configParams

* add tests to eids_spec

* rebase n resolve conflicts
  • Loading branch information
shikharsharma-zeotap authored Sep 11, 2020
1 parent ba8ef86 commit 1e9be73
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 22 deletions.
3 changes: 3 additions & 0 deletions integrationExamples/gpt/userId_example.html
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@
name: "_li_pbid",
expires: 28
}
},
{
name: "zeotapIdPlus"
}],
syncDelay: 5000,
auctionDelay: 1000
Expand Down
3 changes: 2 additions & 1 deletion modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"netIdSystem",
"identityLinkIdSystem",
"sharedIdSystem",
"intentIqIdSystem"
"intentIqIdSystem",
"zeotapIdPlusIdSystem"
],
"adpod": [
"freeWheelAdserverVideo",
Expand Down
5 changes: 5 additions & 0 deletions modules/userId/eids.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ const USER_IDS_CONFIG = {
third: data.third
} : undefined;
}
},
// zeotapIdPlus
'IDP': {
source: 'zeotap.com',
atype: 1
}
};

Expand Down
9 changes: 8 additions & 1 deletion modules/userId/eids.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ userIdAsEids = [
third: 'some-random-id-value'
}
}]
}
},
{
source: 'zeotap.com',
uids: [{
id: 'some-random-id-value',
atype: 1
}]
},
]
```
52 changes: 52 additions & 0 deletions modules/zeotapIdPlusIdSystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* This module adds Zeotap to the User ID module
* The {@link module:modules/userId} module is required
* @module modules/zeotapIdPlusIdSystem
* @requires module:modules/userId
*/
import * as utils from '../src/utils.js'
import {submodule} from '../src/hook.js';
import { getStorageManager } from '../src/storageManager.js';

const ZEOTAP_COOKIE_NAME = 'IDP';
const storage = getStorageManager();

function readCookie() {
return storage.cookiesAreEnabled ? storage.getCookie(ZEOTAP_COOKIE_NAME) : null;
}

function readFromLocalStorage() {
return storage.localStorageIsEnabled ? storage.getDataFromLocalStorage(ZEOTAP_COOKIE_NAME) : null;
}

/** @type {Submodule} */
export const zeotapIdPlusSubmodule = {
/**
* used to link submodule with config
* @type {string}
*/
name: 'zeotapIdPlus',
/**
* decode the stored id value for passing to bid requests
* @function
* @param { Object | string | undefined } value
* @return { Object | string | undefined }
*/
decode(value) {
const id = value ? utils.isStr(value) ? value : utils.isPlainObject(value) ? value.id : undefined : undefined;
return id ? {
'IDP': JSON.parse(atob(id))
} : undefined;
},
/**
* performs action to obtain id and return a value in the callback's response argument
* @function
* @param {SubmoduleParams} configParams
* @return {{id: string | undefined} | undefined}
*/
getId() {
const id = readCookie() || readFromLocalStorage();
return id ? { id } : undefined;
}
};
submodule('userId', zeotapIdPlusSubmodule);
14 changes: 14 additions & 0 deletions test/spec/modules/eids_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,20 @@ describe('eids array generation for known sub-modules', function() {
}]
});
});
it('zeotapIdPlus', function() {
const userId = {
IDP: 'some-random-id-value'
};
const newEids = createEidsArray(userId);
expect(newEids.length).to.equal(1);
expect(newEids[0]).to.deep.equal({
source: 'zeotap.com',
uids: [{
id: 'some-random-id-value',
atype: 1
}]
});
});
});

describe('Negative case', function() {
Expand Down
87 changes: 67 additions & 20 deletions test/spec/modules/userId_spec.js

Large diffs are not rendered by default.

141 changes: 141 additions & 0 deletions test/spec/modules/zeotapIdPlusIdSystem_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { expect } from 'chai';
import find from 'core-js-pure/features/array/find.js';
import { config } from 'src/config.js';
import { newStorageManager } from 'src/storageManager.js';
import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js';
import { zeotapIdPlusSubmodule } from 'modules/zeotapIdPlusIdSystem.js';

const storage = newStorageManager();

const ZEOTAP_COOKIE_NAME = 'IDP';
const ZEOTAP_COOKIE = 'THIS-IS-A-DUMMY-COOKIE';
const ENCODED_ZEOTAP_COOKIE = btoa(JSON.stringify(ZEOTAP_COOKIE));

function getConfigMock() {
return {
userSync: {
syncDelay: 0,
userIds: [{
name: 'zeotapIdPlus'
}]
}
}
}

function getAdUnitMock(code = 'adUnit-code') {
return {
code,
mediaTypes: {banner: {}, native: {}},
sizes: [
[300, 200],
[300, 600]
],
bids: [{
bidder: 'sampleBidder',
params: { placementId: 'banner-only-bidder' }
}]
};
}

function unsetCookie() {
storage.setCookie(ZEOTAP_COOKIE_NAME, '');
}

function unsetLocalStorage() {
storage.setDataInLocalStorage(ZEOTAP_COOKIE_NAME, '');
}

describe('Zeotap ID System', function() {
describe('test method: getId', function() {
afterEach(() => {
unsetCookie();
unsetLocalStorage();
})

it('provides the stored Zeotap id if a cookie exists', function() {
storage.setCookie(
ZEOTAP_COOKIE_NAME,
ENCODED_ZEOTAP_COOKIE,
(new Date(Date.now() + 5000).toUTCString()),
);
let id = zeotapIdPlusSubmodule.getId();
expect(id).to.deep.equal({
id: ENCODED_ZEOTAP_COOKIE
});
});

it('provides the stored Zeotap id if cookie is absent but present in local storage', function() {
storage.setDataInLocalStorage(ZEOTAP_COOKIE_NAME, ENCODED_ZEOTAP_COOKIE);
let id = zeotapIdPlusSubmodule.getId();
expect(id).to.deep.equal({
id: ENCODED_ZEOTAP_COOKIE
});
});

it('returns undefined if both cookie and local storage are empty', function() {
let id = zeotapIdPlusSubmodule.getId();
expect(id).to.be.undefined
})
});

describe('test method: decode', function() {
it('provides the Zeotap ID (IDP) from a stored object', function() {
let zeotapId = {
id: ENCODED_ZEOTAP_COOKIE,
};

expect(zeotapIdPlusSubmodule.decode(zeotapId)).to.deep.equal({
IDP: ZEOTAP_COOKIE
});
});

it('provides the Zeotap ID (IDP) from a stored string', function() {
let zeotapId = ENCODED_ZEOTAP_COOKIE;

expect(zeotapIdPlusSubmodule.decode(zeotapId)).to.deep.equal({
IDP: ZEOTAP_COOKIE
});
});
});

describe('requestBids hook', function() {
let adUnits;

beforeEach(function() {
adUnits = [getAdUnitMock()];
storage.setCookie(
ZEOTAP_COOKIE_NAME,
ENCODED_ZEOTAP_COOKIE,
(new Date(Date.now() + 5000).toUTCString()),
);
setSubmoduleRegistry([zeotapIdPlusSubmodule]);
init(config);
config.setConfig(getConfigMock());
});

afterEach(function() {
unsetCookie();
unsetLocalStorage();
});

it('when a stored Zeotap ID exists it is added to bids', function(done) {
requestBidsHook(function() {
adUnits.forEach(unit => {
unit.bids.forEach(bid => {
expect(bid).to.have.deep.nested.property('userId.IDP');
expect(bid.userId.IDP).to.equal(ZEOTAP_COOKIE);
const zeotapIdAsEid = find(bid.userIdAsEids, e => e.source == 'zeotap.com');
expect(zeotapIdAsEid).to.deep.equal({
source: 'zeotap.com',
uids: [{
id: ZEOTAP_COOKIE,
atype: 1,
}]
});
});
});
done();
}, { adUnits });
});
});
});

0 comments on commit 1e9be73

Please sign in to comment.