Skip to content

Commit

Permalink
NextRoll ID System: add new ID module (#6396)
Browse files Browse the repository at this point in the history
* Add Nextroll ID Module

* Add nextroll to eids

* Make configuration value names consistent with Adapter Module

* Use parnerId instead of sellerId

* Add nextroll to userId and eids md files

* Remove storage configuration

* Rename nextroll -> nextrollId

* Add nextrollId to common ID specs
  • Loading branch information
abijr authored Apr 1, 2021
1 parent 6655277 commit f986df0
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 10 deletions.
1 change: 1 addition & 0 deletions modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"zeotapIdPlusIdSystem",
"haloIdSystem",
"quantcastIdSystem",
"nextrollIdSystem",
"idxIdSystem",
"fabrickIdSystem",
"verizonMediaIdSystem",
Expand Down
50 changes: 50 additions & 0 deletions modules/nextrollIdSystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* This module adds Nextroll ID to the User ID module
* The {@link module:modules/userId} module is required
* @module modules/nextrollIdSystem
* @requires module:modules/userId
*/

import { deepAccess } from '../src/utils.js';
import { submodule } from '../src/hook.js';
import { getStorageManager } from '../src/storageManager.js';

const NEXTROLL_ID_LS_KEY = 'dca0.com';
const KEY_PREFIX = 'AdID:'

export const storage = getStorageManager();

/** @type {Submodule} */
export const nextrollIdSubmodule = {
/**
* used to link submodule with config
* @type {string}
*/
name: 'nextrollId',

/**
* decode the stored id value for passing to bid requests
* @function
* @return {{nextrollId: string} | undefined}
*/
decode(value) {
return value;
},

/**
* performs action to obtain id and return a value.
* @function
* @param {SubmoduleConfig} [config]
* @returns {{id: {nextrollId: string} | undefined}}
*/
getId(config) {
const key = KEY_PREFIX + deepAccess(config, 'params.partnerId', 'undefined');
const dataString = storage.getDataFromLocalStorage(NEXTROLL_ID_LS_KEY) || '{}';
const data = JSON.parse(dataString);
const idValue = deepAccess(data, `${key}.value`);

return { id: idValue ? {nextrollId: idValue} : undefined };
}
};

submodule('userId', nextrollIdSubmodule);
6 changes: 6 additions & 0 deletions modules/userId/eids.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ const USER_IDS_CONFIG = {
atype: 1
},

// nextroll
'nextrollId': {
source: 'nextroll.com',
atype: 1
},

// IDx
'idx': {
source: 'idx.lat',
Expand Down
8 changes: 8 additions & 0 deletions modules/userId/eids.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ userIdAsEids = [
}]
},
{
source: 'nextroll.com',
uids: [{
id: 'some-random-id-value',
atype: 1
}]
},
{
source: 'audigent.com',
uids: [{
Expand Down
7 changes: 6 additions & 1 deletion modules/userId/userId.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,12 @@ pbjs.setConfig({
expires: 90, // Expiration in days
refreshInSeconds: 8*3600 // User Id cache lifetime in seconds, defaulting to 'expires'
},
}, {
}, {
name: 'nextrollId',
params: {
partnerId: "1009", // Set your real NextRoll partner ID here for production
}
}, {
name: 'criteo',
storage: { // It is best not to specify this parameter since the module needs to be called as many times as possible
type: 'html5',
Expand Down
12 changes: 12 additions & 0 deletions test/spec/modules/eids_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,18 @@ describe('eids array generation for known sub-modules', function() {
uids: [{id: 'some-random-id-value', atype: 1}]
});
});

it('NextRollId', function() {
const userId = {
nextrollId: 'some-random-id-value'
};
const newEids = createEidsArray(userId);
expect(newEids.length).to.equal(1);
expect(newEids[0]).to.deep.equal({
source: 'nextroll.com',
uids: [{id: 'some-random-id-value', atype: 1}]
});
});
it('Sharedid', function() {
const userId = {
sharedid: {
Expand Down
56 changes: 56 additions & 0 deletions test/spec/modules/nextrollIdSystem_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { nextrollIdSubmodule, storage } from 'modules/nextrollIdSystem.js';

const LS_VALUE = `{
"AdID":{"id":"adid","key":"AdID"},
"AdID:1002": {"id":"adid","key":"AdID:1002","value":"id_value"}}`;

describe('NextrollId module', function () {
let sandbox = sinon.sandbox.create();
let hasLocalStorageStub;
let getLocalStorageStub;

beforeEach(function() {
hasLocalStorageStub = sandbox.stub(storage, 'hasLocalStorage');
getLocalStorageStub = sandbox.stub(storage, 'getDataFromLocalStorage');
});

afterEach(function () {
sandbox.restore();
})

const testCases = [
{
expect: {
id: {nextrollId: 'id_value'},
},
params: {partnerId: '1002'},
localStorage: LS_VALUE
},
{
expect: {id: undefined},
params: {partnerId: '1003'},
localStorage: LS_VALUE
},
{
expect: {id: undefined},
params: {partnerId: ''},
localStorage: LS_VALUE
},
{
expect: {id: undefined},
params: {partnerId: '102'},
localStorage: undefined
},
{
expect: {id: undefined},
params: undefined,
localStorage: undefined
}
]
testCases.forEach(
(testCase, i) => it(`getId() (TC #${i}) should return the nextroll id if it exists`, function () {
getLocalStorageStub.withArgs('dca0.com').returns(testCase.localStorage);
const id = nextrollIdSubmodule.getId({params: testCase.params});
expect(id).to.be.deep.equal(testCase.expect);
}))
});
21 changes: 12 additions & 9 deletions test/spec/modules/userId_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {identityLinkSubmodule} from 'modules/identityLinkIdSystem.js';
import {liveIntentIdSubmodule} from 'modules/liveIntentIdSystem.js';
import {merkleIdSubmodule} from 'modules/merkleIdSystem.js';
import {netIdSubmodule} from 'modules/netIdSystem.js';
import {nextrollIdSubmodule} from 'modules/nextrollIdSystem.js';
import {intentIqIdSubmodule} from 'modules/intentIqIdSystem.js';
import {zeotapIdPlusSubmodule} from 'modules/zeotapIdPlusIdSystem.js';
import {sharedIdSubmodule} from 'modules/sharedIdSystem.js';
Expand Down Expand Up @@ -475,7 +476,7 @@ describe('User ID', function () {
});

it('handles config with usersync and userIds that are empty objs', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -486,7 +487,7 @@ describe('User ID', function () {
});

it('handles config with usersync and userIds with empty names or that dont match a submodule.name', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -503,15 +504,15 @@ describe('User ID', function () {
});

it('config with 1 configurations should create 1 submodules', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
init(config);
config.setConfig(getConfigMock(['unifiedId', 'unifiedid', 'cookie']));

expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 1 submodules');
});

it('config with 15 configurations should result in 16 submodules add', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
it('config with 16 configurations should result in 17 submodules add', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -538,6 +539,8 @@ describe('User ID', function () {
}, {
name: 'netId',
storage: {name: 'netId', type: 'cookie'}
}, {
name: 'nextrollId'
}, {
name: 'sharedId',
storage: {name: 'sharedid', type: 'cookie'}
Expand All @@ -561,11 +564,11 @@ describe('User ID', function () {
}]
}
});
expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 16 submodules');
expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 17 submodules');
});

it('config syncDelay updates module correctly', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -580,7 +583,7 @@ describe('User ID', function () {
});

it('config auctionDelay updates module correctly', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -595,7 +598,7 @@ describe('User ID', function () {
});

it('config auctionDelay defaults to 0 if not a number', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand Down

0 comments on commit f986df0

Please sign in to comment.