diff --git a/modules/liveIntentIdSystem.js b/modules/liveIntentIdSystem.js index a1f156ca23d..55ef9729ea7 100644 --- a/modules/liveIntentIdSystem.js +++ b/modules/liveIntentIdSystem.js @@ -7,7 +7,7 @@ import { triggerPixel, logError } from '../src/utils.js'; import { ajaxBuilder } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import { LiveConnect } from 'live-connect-js'; // eslint-disable-line prebid/validate-imports +import { StandardLiveConnect } from 'live-connect-js'; // eslint-disable-line prebid/validate-imports import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../src/adapterManager.js'; import {getStorageManager} from '../src/storageManager.js'; import {MODULE_TYPE_UID} from '../src/activities/modules.js'; @@ -48,7 +48,6 @@ export function reset() { window.liQ_instances.forEach(i => i.eventBus.off(EVENTS_TOPIC, setEventFiredFlag)) window.liQ_instances = []; } - liveIntentIdSubmodule.setModuleMode(null) eventFired = false; liveConnect = null; } @@ -156,18 +155,14 @@ function tryFireEvent() { /** @type {Submodule} */ export const liveIntentIdSubmodule = { - moduleMode: process.env.LiveConnectMode, /** * used to link submodule with config * @type {string} */ name: MODULE_NAME, - setModuleMode(mode) { - this.moduleMode = mode - }, getInitializer() { - return (liveConnectConfig, storage, calls) => LiveConnect(liveConnectConfig, storage, calls, this.moduleMode) + return (liveConnectConfig, storage, calls) => StandardLiveConnect(liveConnectConfig, storage, calls) }, /** diff --git a/modules/missenaBidAdapter.js b/modules/missenaBidAdapter.js index a06ba1ce29c..5e68f56ed1c 100644 --- a/modules/missenaBidAdapter.js +++ b/modules/missenaBidAdapter.js @@ -59,9 +59,11 @@ export const spec = { buildRequests: function (validBidRequests, bidderRequest) { const capKey = `missena.missena.capper.remove-bubble.${validBidRequests[0]?.params.apiKey}`; const capping = safeJSONParse(storage.getDataFromLocalStorage(capKey)); + const referer = bidderRequest?.refererInfo?.topmostLocation; if ( typeof capping?.expiry === 'number' && - new Date().getTime() < capping?.expiry + new Date().getTime() < capping?.expiry && + (!capping?.referer || capping?.referer == referer) ) { logInfo('Missena - Capped'); return []; diff --git a/modules/stvBidAdapter.js b/modules/stvBidAdapter.js index 8d368b996fc..0dacf389955 100644 --- a/modules/stvBidAdapter.js +++ b/modules/stvBidAdapter.js @@ -51,6 +51,7 @@ export const spec = { bid_id: bidId, pbver: '$prebid.version$', schain: '', + uids: '', }; if (!isVideoRequest(bidRequest)) { payload._f = 'html'; @@ -61,6 +62,11 @@ export const spec = { delete payload.schain; } + payload.uids = serializeUids(bidRequest); + if (payload.uids == '') { + delete payload.uids; + } + payload.pfilter = { ...params }; delete payload.pfilter.placement; if (params.bcat !== undefined) { delete payload.pfilter.bcat; } @@ -201,7 +207,7 @@ function objectToQueryString(obj, prefix) { let v = obj[p]; str.push((v !== null && typeof v === 'object') ? objectToQueryString(v, k) - : (k == 'schain' ? k + '=' + v : encodeURIComponent(k) + '=' + encodeURIComponent(v))); + : (k == 'schain' || k == 'uids' ? k + '=' + v : encodeURIComponent(k) + '=' + encodeURIComponent(v))); } } return str.join('&'); @@ -227,13 +233,60 @@ function serializeSChain(schain) { ret += encodeURIComponent(node.name ?? ''); ret += ','; ret += encodeURIComponent(node.domain ?? ''); - ret += ','; - ret += encodeURIComponent(node.ext ?? ''); + if (node.ext) { + ret += ','; + ret += encodeURIComponent(node.ext ?? ''); + } } return ret; } +function serializeUids(bidRequest) { + let uids = []; + + let id5 = deepAccess(bidRequest, 'userId.id5id.uid'); + if (id5) { + uids.push(encodeURIComponent('id5:' + id5)); + let id5Linktype = deepAccess(bidRequest, 'userId.id5id.ext.linkType'); + if (id5Linktype) { + uids.push(encodeURIComponent('id5_linktype:' + id5Linktype)); + } + } + let netId = deepAccess(bidRequest, 'userId.netId'); + if (netId) { + uids.push(encodeURIComponent('netid:' + netId)); + } + let uId2 = deepAccess(bidRequest, 'userId.uid2.id'); + if (uId2) { + uids.push(encodeURIComponent('uid2:' + uId2)); + } + let sharedId = deepAccess(bidRequest, 'userId.sharedid.id'); + if (sharedId) { + uids.push(encodeURIComponent('sharedid:' + sharedId)); + } + let liverampId = deepAccess(bidRequest, 'userId.idl_env'); + if (liverampId) { + uids.push(encodeURIComponent('liverampid:' + liverampId)); + } + let criteoId = deepAccess(bidRequest, 'userId.criteoId'); + if (criteoId) { + uids.push(encodeURIComponent('criteoid:' + criteoId)); + } + // documentation missing... + let utiqId = deepAccess(bidRequest, 'userId.utiq.id'); + if (utiqId) { + uids.push(encodeURIComponent('utiq:' + utiqId)); + } else { + utiqId = deepAccess(bidRequest, 'userId.utiq'); + if (utiqId) { + uids.push(encodeURIComponent('utiq:' + utiqId)); + } + } + + return uids.join(','); +} + /** * Check if it's a banner bid request * diff --git a/test/spec/modules/liveIntentIdMinimalSystem_spec.js b/test/spec/modules/liveIntentIdMinimalSystem_spec.js deleted file mode 100644 index 0ada7adc594..00000000000 --- a/test/spec/modules/liveIntentIdMinimalSystem_spec.js +++ /dev/null @@ -1,305 +0,0 @@ -import * as utils from 'src/utils.js'; -import { gdprDataHandler, uspDataHandler } from '../../../src/adapterManager.js'; -import { server } from 'test/mocks/xhr.js'; -import { liveIntentIdSubmodule, reset as resetLiveIntentIdSubmodule, storage } from 'modules/liveIntentIdSystem.js'; - -const PUBLISHER_ID = '89899'; -const defaultConfigParams = { params: {publisherId: PUBLISHER_ID} }; -const responseHeader = {'Content-Type': 'application/json'}; - -describe('LiveIntentMinimalId', function() { - let logErrorStub; - let uspConsentDataStub; - let gdprConsentDataStub; - let getCookieStub; - let getDataFromLocalStorageStub; - let imgStub; - - beforeEach(function() { - liveIntentIdSubmodule.setModuleMode('minimal'); - imgStub = sinon.stub(utils, 'triggerPixel'); - getCookieStub = sinon.stub(storage, 'getCookie'); - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - logErrorStub = sinon.stub(utils, 'logError'); - uspConsentDataStub = sinon.stub(uspDataHandler, 'getConsentData'); - gdprConsentDataStub = sinon.stub(gdprDataHandler, 'getConsentData'); - }); - - afterEach(function() { - imgStub.restore(); - getCookieStub.restore(); - getDataFromLocalStorageStub.restore(); - logErrorStub.restore(); - uspConsentDataStub.restore(); - gdprConsentDataStub.restore(); - liveIntentIdSubmodule.setModuleMode('minimal'); - resetLiveIntentIdSubmodule(); - }); - it('should not fire an event when getId', function() { - uspConsentDataStub.returns('1YNY'); - gdprConsentDataStub.returns({ - gdprApplies: true, - consentString: 'consentDataString' - }) - liveIntentIdSubmodule.getId(defaultConfigParams); - expect(server.requests[0]).to.eql(undefined) - }); - - it('should not return a decoded identifier when the unifiedId is not present in the value', function() { - const result = liveIntentIdSubmodule.decode({ additionalData: 'data' }); - expect(result).to.be.eql({}); - }); - - it('should initialize LiveConnect and send no data', function() { - liveIntentIdSubmodule.getId(defaultConfigParams); - liveIntentIdSubmodule.decode({}, defaultConfigParams); - liveIntentIdSubmodule.getId(defaultConfigParams); - liveIntentIdSubmodule.decode({}, defaultConfigParams); - expect(server.requests.length).to.be.eq(0); - }); - - it('should call the Custom URL of the LiveIntent Identity Exchange endpoint', function() { - getCookieStub.returns(null); - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId({ params: {...defaultConfigParams.params, ...{'url': 'https://dummy.liveintent.com/idex'}} }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://dummy.liveintent.com/idex/prebid/89899?resolve=nonId'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should call the Identity Exchange endpoint with the privided distributorId', function() { - getCookieStub.returns(null); - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId({ params: { fireEventDelay: 1, distributorId: 'did-1111' } }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://idx.liadm.com/idex/did-1111/any?did=did-1111&resolve=nonId'); - request.respond( - 204, - responseHeader - ); - expect(callBackSpy.calledOnceWith({})).to.be.true; - }); - - it('should call the Identity Exchange endpoint without the privided distributorId when appId is provided', function() { - getCookieStub.returns(null); - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId({ params: { fireEventDelay: 1, distributorId: 'did-1111', liCollectConfig: { appId: 'a-0001' } } }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://idx.liadm.com/idex/prebid/any?resolve=nonId'); - request.respond( - 204, - responseHeader - ); - expect(callBackSpy.calledOnceWith({})).to.be.true; - }); - - it('should call the default url of the LiveIntent Identity Exchange endpoint, with a partner', function() { - getCookieStub.returns(null); - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ - 'url': 'https://dummy.liveintent.com/idex', - 'partner': 'rubicon' - } - } }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://dummy.liveintent.com/idex/rubicon/89899?resolve=nonId'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should call the LiveIntent Identity Exchange endpoint, with no additional query params', function() { - getCookieStub.returns(null); - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://idx.liadm.com/idex/prebid/89899?resolve=nonId'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should log an error and continue to callback if ajax request errors', function() { - getCookieStub.returns(null); - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://idx.liadm.com/idex/prebid/89899?resolve=nonId'); - request.respond( - 503, - responseHeader, - 'Unavailable' - ); - expect(logErrorStub.calledOnce).to.be.true; - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should include the LiveConnect identifier when calling the LiveIntent Identity Exchange endpoint', function() { - const oldCookie = 'a-xxxx--123e4567-e89b-12d3-a456-426655440000' - getDataFromLocalStorageStub.withArgs('_li_duid').returns(oldCookie); - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq(`https://idx.liadm.com/idex/prebid/89899?duid=${oldCookie}&resolve=nonId`); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should include the LiveConnect identifier and additional Identifiers to resolve', function() { - const oldCookie = 'a-xxxx--123e4567-e89b-12d3-a456-426655440000' - getDataFromLocalStorageStub.withArgs('_li_duid').returns(oldCookie); - getDataFromLocalStorageStub.withArgs('_thirdPC').returns('third-pc'); - const configParams = { params: { - ...defaultConfigParams.params, - ...{ - 'identifiersToResolve': ['_thirdPC'] - } - }}; - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq(`https://idx.liadm.com/idex/prebid/89899?duid=${oldCookie}&_thirdPC=third-pc&resolve=nonId`); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should include an additional identifier value to resolve even if it is an object', function() { - getCookieStub.returns(null); - getDataFromLocalStorageStub.withArgs('_thirdPC').returns({'key': 'value'}); - const configParams = { params: { - ...defaultConfigParams.params, - ...{ - 'identifiersToResolve': ['_thirdPC'] - } - }}; - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://idx.liadm.com/idex/prebid/89899?_thirdPC=%7B%22key%22%3A%22value%22%7D&resolve=nonId'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should decode a unifiedId to lipbId and remove it', function() { - const result = liveIntentIdSubmodule.decode({ unifiedId: 'data' }); - expect(result).to.eql({'lipb': {'lipbid': 'data'}}); - }); - - it('should decode a nonId to lipbId', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'data' }); - expect(result).to.eql({'lipb': {'lipbid': 'data', 'nonId': 'data'}}); - }); - - it('should resolve extra attributes', function() { - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'foo': true, 'bar': false } } - } }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq(`https://idx.liadm.com/idex/prebid/89899?resolve=nonId&resolve=foo`); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should decode a uid2 to a seperate object when present', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', uid2: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'uid2': 'bar'}, 'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode values with uid2 but no nonId', function() { - const result = liveIntentIdSubmodule.decode({ uid2: 'bar' }); - expect(result).to.eql({'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode a bidswitch id to a seperate object when present', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', bidswitch: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'bidswitch': 'bar'}, 'bidswitch': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode a medianet id to a seperate object when present', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', medianet: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'medianet': 'bar'}, 'medianet': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode a sovrn id to a seperate object when present', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', sovrn: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sovrn': 'bar'}, 'sovrn': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode a magnite id to a seperate object when present', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', magnite: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'magnite': 'bar'}, 'magnite': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode an index id to a seperate object when present', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', index: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'index': 'bar'}, 'index': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode an openx id to a seperate object when present', function () { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', openx: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'openx': 'bar'}, 'openx': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should decode an pubmatic id to a seperate object when present', function() { - const result = liveIntentIdSubmodule.decode({ nonId: 'foo', pubmatic: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'pubmatic': 'bar'}, 'pubmatic': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); - }); - - it('should allow disabling nonId resolution', function() { - let callBackSpy = sinon.spy(); - let submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'nonId': false, 'uid2': true } } - } }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq(`https://idx.liadm.com/idex/prebid/89899?resolve=uid2`); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); -}); diff --git a/test/spec/modules/liveIntentIdSystem_spec.js b/test/spec/modules/liveIntentIdSystem_spec.js index 506c5b312cc..ec6fca70ce3 100644 --- a/test/spec/modules/liveIntentIdSystem_spec.js +++ b/test/spec/modules/liveIntentIdSystem_spec.js @@ -3,7 +3,6 @@ import * as utils from 'src/utils.js'; import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../../../src/adapterManager.js'; import { server } from 'test/mocks/xhr.js'; resetLiveIntentIdSubmodule(); -liveIntentIdSubmodule.setModuleMode('standard') const PUBLISHER_ID = '89899'; const defaultConfigParams = { params: {publisherId: PUBLISHER_ID, fireEventDelay: 1} }; const responseHeader = {'Content-Type': 'application/json'} @@ -18,7 +17,6 @@ describe('LiveIntentId', function() { let imgStub; beforeEach(function() { - liveIntentIdSubmodule.setModuleMode('standard'); imgStub = sinon.stub(utils, 'triggerPixel'); getCookieStub = sinon.stub(storage, 'getCookie'); getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); diff --git a/test/spec/modules/missenaBidAdapter_spec.js b/test/spec/modules/missenaBidAdapter_spec.js index 15f9eff89e7..a51cb8bbac9 100644 --- a/test/spec/modules/missenaBidAdapter_spec.js +++ b/test/spec/modules/missenaBidAdapter_spec.js @@ -2,6 +2,9 @@ import { expect } from 'chai'; import { spec, storage } from 'modules/missenaBidAdapter.js'; import { BANNER } from '../../../src/mediaTypes.js'; +const REFERRER = 'https://referer'; +const REFERRER2 = 'https://referer2'; + describe('Missena Adapter', function () { $$PREBID_GLOBAL$$.bidderSettings = { missena: { @@ -50,7 +53,7 @@ describe('Missena Adapter', function () { gdprApplies: true, }, refererInfo: { - topmostLocation: 'https://referer', + topmostLocation: REFERRER, canonicalUrl: 'https://canonical', }, }; @@ -112,7 +115,7 @@ describe('Missena Adapter', function () { }); it('should send referer information to the request', function () { - expect(payload.referer).to.equal('https://referer'); + expect(payload.referer).to.equal(REFERRER); expect(payload.referer_canonical).to.equal('https://canonical'); }); @@ -146,6 +149,40 @@ describe('Missena Adapter', function () { it('should not participate if capped', function () { expect(cappedRequests.length).to.equal(0); }); + + const localStorageDataSamePage = { + [`missena.missena.capper.remove-bubble.${bid.params.apiKey}`]: + JSON.stringify({ + expiry: new Date().getTime() + 600_000, // 10 min into the future + referer: REFERRER, + }), + }; + + getDataFromLocalStorageStub.callsFake( + (key) => localStorageDataSamePage[key], + ); + const cappedRequestsSamePage = spec.buildRequests(bids, bidderRequest); + + it('should not participate if capped on same page', function () { + expect(cappedRequestsSamePage.length).to.equal(0); + }); + + const localStorageDataOtherPage = { + [`missena.missena.capper.remove-bubble.${bid.params.apiKey}`]: + JSON.stringify({ + expiry: new Date().getTime() + 600_000, // 10 min into the future + referer: REFERRER2, + }), + }; + + getDataFromLocalStorageStub.callsFake( + (key) => localStorageDataOtherPage[key], + ); + const cappedRequestsOtherPage = spec.buildRequests(bids, bidderRequest); + + it('should participate if capped on a different page', function () { + expect(cappedRequestsOtherPage.length).to.equal(2); + }); }); describe('interpretResponse', function () { diff --git a/test/spec/modules/stvBidAdapter_spec.js b/test/spec/modules/stvBidAdapter_spec.js index 41f29cced34..3ef865ed2f1 100644 --- a/test/spec/modules/stvBidAdapter_spec.js +++ b/test/spec/modules/stvBidAdapter_spec.js @@ -71,6 +71,24 @@ describe('stvAdapter', function() { 'hp': 1 } ] + }, + 'userId': { + 'id5id': { + 'uid': '1234', + 'ext': { + 'linkType': 'abc' + } + }, + 'netId': '2345', + 'uid2': { + 'id': '3456', + }, + 'sharedid': { + 'id': '4567', + }, + 'idl_env': '5678', + 'criteoId': '6789', + 'utiq': '7890', } }, { @@ -84,7 +102,27 @@ describe('stvAdapter', function() { ], 'bidId': '30b31c1838de1e2', 'bidderRequestId': '22edbae2733bf62', - 'auctionId': '1d1a030790a476' + 'auctionId': '1d1a030790a476', + 'userId': { // with other utiq variant + 'id5id': { + 'uid': '1234', + 'ext': { + 'linkType': 'abc' + } + }, + 'netId': '2345', + 'uid2': { + 'id': '3456', + }, + 'sharedid': { + 'id': '4567', + }, + 'idl_env': '5678', + 'criteoId': '6789', + 'utiq': { + 'id': '7890' + }, + } }, { 'bidder': 'stv', 'params': { @@ -181,7 +219,7 @@ describe('stvAdapter', function() { expect(request1.method).to.equal('GET'); expect(request1.url).to.equal(ENDPOINT_URL); let data = request1.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid').replace(/pbver=.*?&/g, 'pbver=test&'); - expect(data).to.equal('_f=html&alternative=prebid_js&_ps=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e1&pbver=test&schain=1.0,0!reseller.com,aaaaa,1,BidRequest4,,,&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&gdpr_consent=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&gdpr=true&bcat=IAB2%2CIAB4&dvt=desktop&pbcode=testDiv1&media_types%5Bbanner%5D=300x250'); + expect(data).to.equal('_f=html&alternative=prebid_js&_ps=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e1&pbver=test&schain=1.0,0!reseller.com,aaaaa,1,BidRequest4,,&uids=id5%3A1234,id5_linktype%3Aabc,netid%3A2345,uid2%3A3456,sharedid%3A4567,liverampid%3A5678,criteoid%3A6789,utiq%3A7890&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&gdpr_consent=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&gdpr=true&bcat=IAB2%2CIAB4&dvt=desktop&pbcode=testDiv1&media_types%5Bbanner%5D=300x250'); }); var request2 = spec.buildRequests([bidRequests[1]], bidderRequest)[0]; @@ -189,7 +227,7 @@ describe('stvAdapter', function() { expect(request2.method).to.equal('GET'); expect(request2.url).to.equal(ENDPOINT_URL); let data = request2.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid').replace(/pbver=.*?&/g, 'pbver=test&'); - expect(data).to.equal('_f=html&alternative=prebid_js&_ps=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e2&pbver=test&gdpr_consent=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&gdpr=true&prebidDevMode=1&media_types%5Bbanner%5D=300x250'); + expect(data).to.equal('_f=html&alternative=prebid_js&_ps=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e2&pbver=test&uids=id5%3A1234,id5_linktype%3Aabc,netid%3A2345,uid2%3A3456,sharedid%3A4567,liverampid%3A5678,criteoid%3A6789,utiq%3A7890&gdpr_consent=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&gdpr=true&prebidDevMode=1&media_types%5Bbanner%5D=300x250'); }); // Without gdprConsent diff --git a/test/spec/modules/viantOrtbBidAdapter_spec.js b/test/spec/modules/viantOrtbBidAdapter_spec.js index 6d5014bd639..73fdb7f3dc8 100644 --- a/test/spec/modules/viantOrtbBidAdapter_spec.js +++ b/test/spec/modules/viantOrtbBidAdapter_spec.js @@ -109,6 +109,49 @@ describe('viantOrtbBidAdapter', function () { }); }); }); + + describe('native', function () { + describe('and request config uses mediaTypes', () => { + function makeBid() { + return { + 'bidder': 'viant', + 'params': { + 'unit': '12345678', + 'delDomain': 'test-del-domain', + 'publisherId': '464', + 'placementId': 'some-PlacementId_2' + }, + 'mediaTypes': { + 'video': { + 'context': 'instream', + 'playerSize': [[640, 480]], + 'mimes': ['video/mp4'], + 'protocols': [1, 2, 3, 4, 5, 6, 7, 8], + 'api': [1, 3], + 'skip': 1, + 'skipafter': 5, + 'minduration': 10, + 'maxduration': 30 + } + }, + 'adUnitCode': 'adunit-code', + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' + } + } + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(makeBid())).to.equal(true); + }); + + it('should return false when required params are not passed', function () { + let nativeBidWithMediaTypes = Object.assign({}, makeBid()); + nativeBidWithMediaTypes.params = {}; + expect(spec.isBidRequestValid(nativeBidWithMediaTypes)).to.equal(false); + }); + }); + }); }); describe('buildRequests-banner', function () { diff --git a/webpack.conf.js b/webpack.conf.js index 0ead550e446..6687c71bf8b 100644 --- a/webpack.conf.js +++ b/webpack.conf.js @@ -1,7 +1,6 @@ const TerserPlugin = require('terser-webpack-plugin'); var prebid = require('./package.json'); var path = require('path'); -var webpack = require('webpack'); var helpers = require('./gulpHelpers.js'); var { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); var argv = require('yargs').argv; @@ -10,7 +9,6 @@ const babelConfig = require('./babelConfig.js')({disableFeatures: helpers.getDis const {WebpackManifestPlugin} = require('webpack-manifest-plugin') var plugins = [ - new webpack.EnvironmentPlugin({'LiveConnectMode': null}), new WebpackManifestPlugin({ fileName: 'dependencies.json', generate: (seed, files) => {