From 74d01b32cf1d76967533825560eb22be44de823a Mon Sep 17 00:00:00 2001 From: Maurice Roach Date: Mon, 4 Jan 2021 15:21:24 -0500 Subject: [PATCH 1/2] Add tapad id submodule --- modules/.submodules.json | 3 +- modules/tapadIdSystem.js | 78 +++++++++++++++++++++++++ test/spec/modules/tapadIdSystem_spec.js | 55 +++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 modules/tapadIdSystem.js create mode 100644 test/spec/modules/tapadIdSystem_spec.js diff --git a/modules/.submodules.json b/modules/.submodules.json index 4e02391129a..fc69dd276a3 100644 --- a/modules/.submodules.json +++ b/modules/.submodules.json @@ -19,7 +19,8 @@ "idxIdSystem", "fabrickIdSystem", "verizonMediaIdSystem", - "pubProvidedIdSystem" + "pubProvidedIdSystem", + "tapadIdSystem" ], "adpod": [ "freeWheelAdserverVideo", diff --git a/modules/tapadIdSystem.js b/modules/tapadIdSystem.js new file mode 100644 index 00000000000..d816cdca886 --- /dev/null +++ b/modules/tapadIdSystem.js @@ -0,0 +1,78 @@ +import { uspDataHandler } from '../src/adapterManager.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import * as ajax from '../src/ajax.js' +import * as utils from '../src/utils.js'; + +export const storage = getStorageManager(); +const cookiesMaxAge = 7 * 24 * 60 * 60 * 1000; // 60 days +export const defaultExpirationString = new Date(utils.timestamp() + cookiesMaxAge).toString(); +export const pastDateString = new Date(0).toString(); +export const tapadCookieKey = 'tapad_id'; +export const graphUrl = 'https://realtime-graph-access-zxvhwknfeq-uc.a.run.app/v1/graph'; + +function saveOnAllStorages(key, value, expiration = defaultExpirationString) { + storage.setCookie(key, typeof value === 'object' ? JSON.stringify(value) : value, expiration); + storage.setDataInLocalStorage(key, JSON.stringify(value)); +} + +function deleteFromAllStorages(key) { + storage.setCookie(key, undefined, pastDateString); + storage.removeDataFromLocalStorage(key); +} + +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 || {}; + const expiration = config.storage && config.storage.expires + ? new Date(utils.timestamp() + config.storage.expires * 24 * 60 * 60 * 1000).toString() + : undefined; + + 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')) { + saveOnAllStorages(tapadCookieKey, responseJson.tapadId, expiration) + complete(responseJson.tapadId) + } + }, + error: (_, e) => { + if (e.status === 404) { + deleteFromAllStorages(tapadCookieKey); + complete(undefined); + } + if (e.status === 403) { + utils.logMessage('Invalid Company Id. Contact prebid@tapad.com for assistance.') + } + } + } + ) + } + } + } +} +submodule('userId', tapadIdSubmodule); diff --git a/test/spec/modules/tapadIdSystem_spec.js b/test/spec/modules/tapadIdSystem_spec.js new file mode 100644 index 00000000000..fca7b7b9cd8 --- /dev/null +++ b/test/spec/modules/tapadIdSystem_spec.js @@ -0,0 +1,55 @@ +import { tapadIdSubmodule, graphUrl, storage, tapadCookieKey, pastDateString, defaultExpirationString } from 'modules/tapadIdSystem.js'; +import * as utils from 'src/utils.js'; + +import { server } from 'test/mocks/xhr.js'; + +describe('TapadIdSystem', function () { + describe('getId', function() { + let setCookieSpy; + beforeEach(() => { + setCookieSpy = sinon.spy(storage, 'setCookie'); + }) + afterEach(() => { + setCookieSpy.restore() + }) + + it('should call to real time graph endpoint and handle valid response', function() { + const callbackSpy = sinon.spy() + const callback = tapadIdSubmodule.getId({ + params: { companyId: 12345 } + }).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'); + expect(setCookieSpy.lastCall.calledWith(tapadCookieKey, 'your-tapad-id', defaultExpirationString)).to.be.true + }) + + it('should remove stored tapadId if not found', function() { + const callbackSpy = sinon.spy() + const callback = tapadIdSubmodule.getId({}).callback + callback(callbackSpy); + + const request = server.requests[0] + + request.respond(404) + expect(callbackSpy.lastCall.lastArg).to.be.undefined; + expect(setCookieSpy.lastCall.calledWith(tapadCookieKey, undefined, pastDateString)).to.be.true + }) + it('should log message with invalid company id', function() { + const logMessageSpy = sinon.spy(utils, 'logMessage'); + const callbackSpy = sinon.spy() + const callback = tapadIdSubmodule.getId({}).callback + callback(callbackSpy); + + const request = server.requests[0] + + request.respond(403) + expect(logMessageSpy.lastCall.lastArg).to.eq('Invalid Company Id. Contact prebid@tapad.com for assistance.') + logMessageSpy.restore() + }) + }) +}) From 7f2e9ee672ac7d645a7891d9798dfbbe6de76688 Mon Sep 17 00:00:00 2001 From: Maurice Roach Date: Thu, 14 Jan 2021 10:29:12 -0500 Subject: [PATCH 2/2] clean and add specs --- modules/tapadIdSystem.js | 31 +++-------- modules/userId/eids.js | 4 ++ modules/userId/eids.md | 7 +++ test/spec/modules/eids_spec.js | 12 ++++ test/spec/modules/tapadIdSystem_spec.js | 74 ++++++++++++++----------- test/spec/modules/userId_spec.js | 58 ++++++++++++++----- 6 files changed, 116 insertions(+), 70 deletions(-) diff --git a/modules/tapadIdSystem.js b/modules/tapadIdSystem.js index d816cdca886..e4dfe304585 100644 --- a/modules/tapadIdSystem.js +++ b/modules/tapadIdSystem.js @@ -1,26 +1,10 @@ import { uspDataHandler } from '../src/adapterManager.js'; import { submodule } from '../src/hook.js'; -import { getStorageManager } from '../src/storageManager.js'; import * as ajax from '../src/ajax.js' import * as utils from '../src/utils.js'; -export const storage = getStorageManager(); -const cookiesMaxAge = 7 * 24 * 60 * 60 * 1000; // 60 days -export const defaultExpirationString = new Date(utils.timestamp() + cookiesMaxAge).toString(); -export const pastDateString = new Date(0).toString(); -export const tapadCookieKey = 'tapad_id'; export const graphUrl = 'https://realtime-graph-access-zxvhwknfeq-uc.a.run.app/v1/graph'; -function saveOnAllStorages(key, value, expiration = defaultExpirationString) { - storage.setCookie(key, typeof value === 'object' ? JSON.stringify(value) : value, expiration); - storage.setDataInLocalStorage(key, JSON.stringify(value)); -} - -function deleteFromAllStorages(key) { - storage.setCookie(key, undefined, pastDateString); - storage.removeDataFromLocalStorage(key); -} - export const tapadIdSubmodule = { name: 'tapadId', /** @@ -44,9 +28,10 @@ export const tapadIdSubmodule = { return { id: undefined }; } const configParams = config.params || {}; - const expiration = config.storage && config.storage.expires - ? new Date(utils.timestamp() + config.storage.expires * 24 * 60 * 60 * 1000).toString() - : undefined; + + if (configParams.companyId == null || isNaN(Number(configParams.companyId))) { + utils.logMessage('Please provide a valid Company Id. Contact prebid@tapad.com for assistance.'); + } return { callback: (complete) => { @@ -56,21 +41,19 @@ export const tapadIdSubmodule = { success: (response) => { const responseJson = JSON.parse(response); if (responseJson.hasOwnProperty('tapadId')) { - saveOnAllStorages(tapadCookieKey, responseJson.tapadId, expiration) - complete(responseJson.tapadId) + complete(responseJson.tapadId); } }, error: (_, e) => { if (e.status === 404) { - deleteFromAllStorages(tapadCookieKey); complete(undefined); } if (e.status === 403) { - utils.logMessage('Invalid Company Id. Contact prebid@tapad.com for assistance.') + utils.logMessage('Invalid Company Id. Contact prebid@tapad.com for assistance.'); } } } - ) + ); } } } diff --git a/modules/userId/eids.js b/modules/userId/eids.js index d714d09962d..80e336d206a 100644 --- a/modules/userId/eids.js +++ b/modules/userId/eids.js @@ -168,6 +168,10 @@ const USER_IDS_CONFIG = { 'fabrickId': { source: 'neustar.biz', atype: 1 + }, + 'tapadId': { + source: 'tapad.com', + atype: 1 } }; diff --git a/modules/userId/eids.md b/modules/userId/eids.md index fecf7e888bf..847e43545d6 100644 --- a/modules/userId/eids.md +++ b/modules/userId/eids.md @@ -141,6 +141,13 @@ userIdAsEids = [ id: 'some-random-id-value', atype: 1 }] + }, + { + source: 'tapad.com', + uids: [{ + id: 'some-random-id-value', + atype: 1 + }] } ] ``` diff --git a/test/spec/modules/eids_spec.js b/test/spec/modules/eids_spec.js index 26dbad2f153..59b0c1f001d 100644 --- a/test/spec/modules/eids_spec.js +++ b/test/spec/modules/eids_spec.js @@ -169,6 +169,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' diff --git a/test/spec/modules/tapadIdSystem_spec.js b/test/spec/modules/tapadIdSystem_spec.js index fca7b7b9cd8..bc31f1d37ba 100644 --- a/test/spec/modules/tapadIdSystem_spec.js +++ b/test/spec/modules/tapadIdSystem_spec.js @@ -1,55 +1,65 @@ -import { tapadIdSubmodule, graphUrl, storage, tapadCookieKey, pastDateString, defaultExpirationString } from 'modules/tapadIdSystem.js'; +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() { - let setCookieSpy; - beforeEach(() => { - setCookieSpy = sinon.spy(storage, 'setCookie'); - }) - afterEach(() => { - setCookieSpy.restore() - }) - + 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({ - params: { companyId: 12345 } - }).callback + 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`) + 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' })) + request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ tapadId: 'your-tapad-id' })); expect(callbackSpy.lastCall.lastArg).to.eq('your-tapad-id'); - expect(setCookieSpy.lastCall.calledWith(tapadCookieKey, 'your-tapad-id', defaultExpirationString)).to.be.true - }) + }); it('should remove stored tapadId if not found', function() { - const callbackSpy = sinon.spy() - const callback = tapadIdSubmodule.getId({}).callback + const callbackSpy = sinon.spy(); + const callback = tapadIdSubmodule.getId(config).callback; callback(callbackSpy); - const request = server.requests[0] + const request = server.requests[0]; - request.respond(404) + request.respond(404); expect(callbackSpy.lastCall.lastArg).to.be.undefined; - expect(setCookieSpy.lastCall.calledWith(tapadCookieKey, undefined, pastDateString)).to.be.true - }) + }); + it('should log message with invalid company id', function() { const logMessageSpy = sinon.spy(utils, 'logMessage'); - const callbackSpy = sinon.spy() - const callback = tapadIdSubmodule.getId({}).callback + 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 prebid@tapad.com 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); - const request = server.requests[0] + expect(logMessageSpy.lastCall.lastArg).to.eq('Please provide a valid Company Id. Contact prebid@tapad.com 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); - request.respond(403) - expect(logMessageSpy.lastCall.lastArg).to.eq('Invalid Company Id. Contact prebid@tapad.com for assistance.') - logMessageSpy.restore() - }) - }) + expect(logMessageSpy.lastCall.lastArg).to.eq('Please provide a valid Company Id. Contact prebid@tapad.com for assistance.'); + logMessageSpy.restore(); + }); + }); }) diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 981ebb5f50e..e937fa3d631 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -36,6 +36,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; @@ -454,7 +455,7 @@ 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' @@ -462,14 +463,14 @@ describe('User ID', function () { }); 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: { @@ -480,7 +481,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: { @@ -497,15 +498,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: { @@ -545,14 +546,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: { @@ -567,7 +571,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: { @@ -582,7 +586,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: { @@ -984,6 +988,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'})); @@ -1481,7 +1508,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'], @@ -1493,7 +1520,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 => { @@ -1586,6 +1614,7 @@ describe('User ID', function () { attachIdSystem(zeotapIdPlusSubmodule); attachIdSystem(haloIdSubmodule); attachIdSystem(criteoIdSubmodule); + attachIdSystem(tapadIdSubmodule); config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], ['unifiedId', 'unifiedid', 'cookie'], @@ -1597,7 +1626,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 => {