Skip to content

Commit

Permalink
Add tapad id submodule (prebid#6167)
Browse files Browse the repository at this point in the history
* Add tapad id submodule

* clean and add specs
  • Loading branch information
moeroach94 authored and stsepelin committed May 28, 2021
1 parent 264f75d commit 766ccf8
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 15 deletions.
3 changes: 2 additions & 1 deletion modules/.submodules.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"idxIdSystem",
"fabrickIdSystem",
"verizonMediaIdSystem",
"pubProvidedIdSystem"
"pubProvidedIdSystem",
"tapadIdSystem"
],
"adpod": [
"freeWheelAdserverVideo",
Expand Down
61 changes: 61 additions & 0 deletions modules/tapadIdSystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { uspDataHandler } from '../src/adapterManager.js';
import { submodule } from '../src/hook.js';
import * as ajax from '../src/ajax.js'
import * as utils from '../src/utils.js';

export const graphUrl = 'https://realtime-graph-access-zxvhwknfeq-uc.a.run.app/v1/graph';

export const tapadIdSubmodule = {
name: 'tapadId',
/**
* decode the stored id value for passing to bid requests
* @function
* @returns {{tapadId: string} | undefined}
*/
decode(id) {
return { tapadId: id };
},
/*
* @function
* @summary initiate Real Time Graph
* @param {SubmoduleParams} [configParams]
* @param {ConsentData} [consentData]
* @returns {IdResponse }}
*/
getId(config) {
const uspData = uspDataHandler.getConsentData();
if (uspData && uspData !== '1---') {
return { id: undefined };
}
const configParams = config.params || {};

if (configParams.companyId == null || isNaN(Number(configParams.companyId))) {
utils.logMessage('Please provide a valid Company Id. Contact [email protected] for assistance.');
}

return {
callback: (complete) => {
ajax.ajaxBuilder(10000)(
`${graphUrl}?company_id=${configParams.companyId}&tapad_id_type=TAPAD_ID`,
{
success: (response) => {
const responseJson = JSON.parse(response);
if (responseJson.hasOwnProperty('tapadId')) {
complete(responseJson.tapadId);
}
},
error: (_, e) => {
if (e.status === 404) {
complete(undefined);
}
if (e.status === 403) {
utils.logMessage('Invalid Company Id. Contact [email protected] for assistance.');
}
}
}
);
}
}
}
}
submodule('userId', tapadIdSubmodule);
4 changes: 4 additions & 0 deletions modules/userId/eids.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ const USER_IDS_CONFIG = {
'fabrickId': {
source: 'neustar.biz',
atype: 1
},
'tapadId': {
source: 'tapad.com',
atype: 1
}
};

Expand Down
7 changes: 7 additions & 0 deletions modules/userId/eids.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ userIdAsEids = [
id: 'some-random-id-value',
atype: 1
}]
},
{
source: 'tapad.com',
uids: [{
id: 'some-random-id-value',
atype: 1
}]
}
]
```
12 changes: 12 additions & 0 deletions test/spec/modules/eids_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ describe('eids array generation for known sub-modules', function() {
});
});

it('tapadId', function() {
const userId = {
tapadId: 'some-random-id-value'
};
const newEids = createEidsArray(userId);
expect(newEids.length).to.equal(1);
expect(newEids[0]).to.deep.equal({
source: 'tapad.com',
uids: [{id: 'some-random-id-value', atype: 1}]
});
});

it('NetId', function() {
const userId = {
netId: 'some-random-id-value'
Expand Down
65 changes: 65 additions & 0 deletions test/spec/modules/tapadIdSystem_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { tapadIdSubmodule, graphUrl } from 'modules/tapadIdSystem.js';
import * as utils from 'src/utils.js';

import { server } from 'test/mocks/xhr.js';

describe('TapadIdSystem', function () {
describe('getId', function() {
const config = { params: { companyId: 12345 } };
it('should call to real time graph endpoint and handle valid response', function() {
const callbackSpy = sinon.spy();
const callback = tapadIdSubmodule.getId(config).callback;
callback(callbackSpy);

const request = server.requests[0];
expect(request.url).to.eq(`${graphUrl}?company_id=12345&tapad_id_type=TAPAD_ID`);

request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ tapadId: 'your-tapad-id' }));
expect(callbackSpy.lastCall.lastArg).to.eq('your-tapad-id');
});

it('should remove stored tapadId if not found', function() {
const callbackSpy = sinon.spy();
const callback = tapadIdSubmodule.getId(config).callback;
callback(callbackSpy);

const request = server.requests[0];

request.respond(404);
expect(callbackSpy.lastCall.lastArg).to.be.undefined;
});

it('should log message with invalid company id', function() {
const logMessageSpy = sinon.spy(utils, 'logMessage');
const callbackSpy = sinon.spy();
const callback = tapadIdSubmodule.getId(config).callback;
callback(callbackSpy);

const request = server.requests[0];

request.respond(403);
expect(logMessageSpy.lastCall.lastArg).to.eq('Invalid Company Id. Contact [email protected] for assistance.');
logMessageSpy.restore();
});

it('should log message if company id not given', function() {
const logMessageSpy = sinon.spy(utils, 'logMessage');
const callbackSpy = sinon.spy();
const callback = tapadIdSubmodule.getId({}).callback;
callback(callbackSpy);

expect(logMessageSpy.lastCall.lastArg).to.eq('Please provide a valid Company Id. Contact [email protected] for assistance.');
logMessageSpy.restore();
});

it('should log message if company id is incorrect format', function() {
const logMessageSpy = sinon.spy(utils, 'logMessage');
const callbackSpy = sinon.spy();
const callback = tapadIdSubmodule.getId({ params: { companyId: 'notANumber' } }).callback;
callback(callbackSpy);

expect(logMessageSpy.lastCall.lastArg).to.eq('Please provide a valid Company Id. Contact [email protected] for assistance.');
logMessageSpy.restore();
});
});
})
58 changes: 44 additions & 14 deletions test/spec/modules/userId_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {sharedIdSubmodule} from 'modules/sharedIdSystem.js';
import {haloIdSubmodule} from 'modules/haloIdSystem.js';
import {pubProvidedIdSubmodule} from 'modules/pubProvidedIdSystem.js';
import {criteoIdSubmodule} from 'modules/criteoIdSystem.js';
import {tapadIdSubmodule} from 'modules/tapadIdSystem.js';

let assert = require('chai').assert;
let expect = require('chai').expect;
Expand Down Expand Up @@ -456,22 +457,22 @@ describe('User ID', function () {
});

it('handles config with no usersync object', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig({});
// usersync is undefined, and no logInfo message for 'User ID - usersync config updated'
expect(typeof utils.logInfo.args[0]).to.equal('undefined');
});

it('handles config with empty usersync object', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig({userSync: {}});
expect(typeof utils.logInfo.args[0]).to.equal('undefined');
});

it('handles config with usersync and userIds that are empty objs', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -482,7 +483,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]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -499,15 +500,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]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
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 13 configurations should result in 13 submodules add', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule]);
it('config with 14 configurations should result in 14 submodules add', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand Down Expand Up @@ -547,14 +548,17 @@ describe('User ID', function () {
name: 'zeotapIdPlus'
}, {
name: 'criteo'
}, {
name: 'tapadId',
storage: {name: 'tapad_id', type: 'cookie'}
}]
}
});
expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 13 submodules');
expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 14 submodules');
});

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

it('config auctionDelay updates module correctly', function () {
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand All @@ -584,7 +588,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]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig({
userSync: {
Expand Down Expand Up @@ -986,6 +990,29 @@ describe('User ID', function () {
}, {adUnits});
});

it('test hook from tapadIdModule cookie', function (done) {
coreStorage.setCookie('tapad_id', 'test-tapad-id', (new Date(Date.now() + 100000).toUTCString()));

setSubmoduleRegistry([tapadIdSubmodule]);
init(config);
config.setConfig(getConfigMock(['tapadId', 'tapad_id', 'cookie']));

requestBidsHook(function () {
adUnits.forEach(unit => {
unit.bids.forEach(bid => {
expect(bid).to.have.deep.nested.property('userId.tapadId');
expect(bid.userId.tapadId).to.equal('test-tapad-id');
expect(bid.userIdAsEids[0]).to.deep.equal({
source: 'tapad.com',
uids: [{id: 'test-tapad-id', atype: 1}]
});
});
})
coreStorage.setCookie('tapad_id', '', EXPIRED_COOKIE_DATE);
done();
}, {adUnits});
});

it('test hook from liveIntentId html5', function (done) {
// simulate existing browser local storage values
localStorage.setItem('_li_pbid', JSON.stringify({'unifiedId': 'random-ls-identifier'}));
Expand Down Expand Up @@ -1483,7 +1510,7 @@ describe('User ID', function () {
coreStorage.setCookie('haloId', JSON.stringify({'haloId': 'testHaloId'}), (new Date(Date.now() + 5000).toUTCString()));
coreStorage.setCookie('storage_criteo', JSON.stringify({'criteoId': 'test_bidid'}), (new Date(Date.now() + 5000).toUTCString()));

setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, criteoIdSubmodule]);
setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, criteoIdSubmodule, tapadIdSubmodule]);
init(config);
config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'],
['unifiedId', 'unifiedid', 'cookie'],
Expand All @@ -1495,7 +1522,8 @@ describe('User ID', function () {
['intentIqId', 'intentIqId', 'cookie'],
['zeotapIdPlus', 'IDP', 'cookie'],
['haloId', 'haloId', 'cookie'],
['criteo', 'storage_criteo', 'cookie']));
['criteo', 'storage_criteo', 'cookie'],
['tapadId', 'tapad_id', 'cookie']));

requestBidsHook(function () {
adUnits.forEach(unit => {
Expand Down Expand Up @@ -1588,6 +1616,7 @@ describe('User ID', function () {
attachIdSystem(zeotapIdPlusSubmodule);
attachIdSystem(haloIdSubmodule);
attachIdSystem(criteoIdSubmodule);
attachIdSystem(tapadIdSubmodule);

config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'],
['unifiedId', 'unifiedid', 'cookie'],
Expand All @@ -1599,7 +1628,8 @@ describe('User ID', function () {
['intentIqId', 'intentIqId', 'cookie'],
['zeotapIdPlus', 'IDP', 'cookie'],
['haloId', 'haloId', 'cookie'],
['criteo', 'storage_criteo', 'cookie']));
['criteo', 'storage_criteo', 'cookie'],
['tapadId', 'tapad_id', 'cookie']));

requestBidsHook(function () {
adUnits.forEach(unit => {
Expand Down

0 comments on commit 766ccf8

Please sign in to comment.