Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NextRoll ID System: add new ID submodule #6396

Merged
merged 9 commits into from
Apr 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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