From 87375b8fb1079c402558a03126ab6912d6c75429 Mon Sep 17 00:00:00 2001 From: iosfaisal <100519197+iosfaisal@users.noreply.github.com> Date: Tue, 5 Apr 2022 13:02:26 +0600 Subject: [PATCH 01/20] PBS Implementation - Work In Progress --- modules/improvedigitalBidAdapter.js | 75 +++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index c696dabc64a..579735d7ee2 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -9,9 +9,18 @@ import {Renderer} from '../src/Renderer.js'; import {createEidsArray} from './userId/eids.js'; const BIDDER_CODE = 'improvedigital'; -const REQUEST_URL = 'https://ad.360yield.com/pb'; const CREATIVE_TTL = 300; +const REQUEST = { + PB_URL: 'https://ad.360yield.com/pb', + PBS_URL: 'https://pbs.360yield.com/openrtb2/auction', + PBS_SYNC_URL: 'https://localhost:3001/load-cookie.html?endpoint=improvedigital&gdpr=$$GDPR$$&gdpr_consent=$$GDPR_CONSENT$$', + getUrl(pbs = false) { + return pbs ? this.PBS_URL : this.PB_URL; + }, + BIDDER_REQUEST: [], +}; + const VIDEO_PARAMS = { DEFAULT_MIMES: ['video/mp4'], SUPPORTED_PROPERTIES: ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', @@ -145,6 +154,8 @@ export const spec = { deepSetValue(request, 'user.ext.eids', eids.length ? eids : undefined); } + REQUEST.BIDDER_REQUEST = bidderRequest; + return ID_REQUEST.buildServerRequests(request, bidRequests, bidderRequest); }, @@ -206,7 +217,7 @@ export const spec = { * @param {ServerResponse[]} serverResponses List of server's responses. * @return {UserSync[]} The user syncs which should be dropped. */ - getUserSyncs(syncOptions, serverResponses) { + getUserSyncs(syncOptions, serverResponses, gdprConsent) { if (syncOptions.pixelEnabled) { const syncs = []; serverResponses.forEach(response => { @@ -216,8 +227,31 @@ export const spec = { syncs.push(syncElement); } }); + // FOR PBS MODE + const seatBids = deepAccess(response, 'body.seatbid.0.bid', []); // @FIXME + seatBids.forEach(bid => { + const bidRequest = getBidRequest(bid.impid, [REQUEST.BIDDER_REQUEST]); + const pbsConfig = ID_REQUEST.pbsConfig(bidRequest.params); + if (pbsConfig.pbs) { + syncs.push({ + type: 'iframe', + url: REQUEST.PBS_SYNC_URL + .replace('$$GDPR$$', ID_UTIL.toBit(gdprConsent.gdprApplies)) + .replace('$$GDPR_CONSENT$$', gdprConsent.consentString) + , + }); + } + }) + }); + return syncs.map(sync => { + if (typeof sync === 'object' && sync.type && sync.url) { + return { + type: sync.type, + url: sync.url, + } + } + return { type: 'image', url: sync } }); - return syncs.map(sync => ({ type: 'image', url: sync })); } return []; } @@ -229,31 +263,40 @@ const ID_REQUEST = { buildServerRequests(requestObject, bidRequests, bidderRequest) { const requests = []; if (config.getConfig('improvedigital.singleRequest') === true) { - requestObject.imp = bidRequests.map((bidRequest) => this.buildImp(bidRequest)); - requests[0] = this.formatRequest(requestObject, bidderRequest); + const pbsConfig = this.pbsConfig(); + requestObject.imp = bidRequests.map((bidRequest) => this.buildImp(bidRequest, pbsConfig)); + requests[0] = this.formatRequest(requestObject, bidderRequest, pbsConfig); } else { bidRequests.map((bidRequest) => { const request = deepClone(requestObject); + const pbsConfig = this.pbsConfig(bidRequest.params); request.id = bidRequest.bidId || getUniqueIdentifierStr(); - request.imp = [this.buildImp(bidRequest)]; + request.imp = [this.buildImp(bidRequest, pbsConfig)]; deepSetValue(request, 'source.tid', bidRequest.transactionId); - requests.push(this.formatRequest(request, bidderRequest)); + requests.push(this.formatRequest(request, bidderRequest, pbsConfig)); }); } return requests; }, - formatRequest(request, bidderRequest) { + formatRequest(request, bidderRequest, pbsConfig) { return { method: 'POST', - url: REQUEST_URL, + url: REQUEST.getUrl(pbsConfig.pbs), data: JSON.stringify(request), bidderRequest } }, - buildImp(bidRequest) { + pbsConfig(bidParams = {}) { + return mergeDeep({}, { + pbs: config.getConfig('improvedigital.pbs') === true, + }, bidParams) + }, + + buildImp(bidRequest, pbsConfig) { + const bidderCode = pbsConfig.pbs ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; const imp = { id: getBidIdParameter('bidId', bidRequest) || getUniqueIdentifierStr(), secure: ID_UTIL.toBit(window.location.protocol === 'https:'), @@ -269,13 +312,17 @@ const ID_REQUEST = { const placementId = getBidIdParameter('placementId', bidRequest.params); if (placementId) { - deepSetValue(imp, 'ext.bidder.placementId', placementId); + deepSetValue(imp, bidderCode + '.placementId', placementId); + // When PBS Mode Enabled + if (pbsConfig.pbs) { + deepSetValue(imp, 'ext.prebid.storedrequest.id', placementId); + } } else { - deepSetValue(imp, 'ext.bidder.publisherId', getBidIdParameter('publisherId', bidRequest.params)); - deepSetValue(imp, 'ext.bidder.placementKey', getBidIdParameter('placementKey', bidRequest.params)); + deepSetValue(imp, bidderCode + '.publisherId', getBidIdParameter('publisherId', bidRequest.params)); + deepSetValue(imp, bidderCode + '.placementKey', getBidIdParameter('placementKey', bidRequest.params)); } - deepSetValue(imp, 'ext.bidder.keyValues', getBidIdParameter('keyValues', bidRequest.params) || undefined); + deepSetValue(imp, bidderCode + '.keyValues', getBidIdParameter('keyValues', bidRequest.params) || undefined); // Adding GPID const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid') || From ad32f2c22c4bbfd95696a30f49a2694db8812f22 Mon Sep 17 00:00:00 2001 From: iosfaisal <100519197+iosfaisal@users.noreply.github.com> Date: Tue, 5 Apr 2022 14:49:13 +0600 Subject: [PATCH 02/20] PBS Implementation - Work In Progress --- modules/improvedigitalBidAdapter.js | 43 +++++++++++++++++------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 579735d7ee2..e4b93f867b5 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -95,7 +95,8 @@ export const spec = { version: '$prebid.version$', } } - } + }, + test: 1 }; // Device @@ -154,7 +155,7 @@ export const spec = { deepSetValue(request, 'user.ext.eids', eids.length ? eids : undefined); } - REQUEST.BIDDER_REQUEST = bidderRequest; + REQUEST.BIDDER_REQUEST.push(bidderRequest); return ID_REQUEST.buildServerRequests(request, bidRequests, bidderRequest); }, @@ -188,11 +189,11 @@ export const spec = { cpm: bidObject.price, creativeId: bidObject.crid, currency: serverResponse.body.cur.toUpperCase() || 'USD', - dealId: (typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined, + dealId: (idExt && typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined, meta: { advertiserDomains: bidObject.adomain ? bidObject.adomain : [] }, - netRevenue: idExt.is_net || false, + netRevenue: idExt && idExt.is_net || false, ttl: CREATIVE_TTL } @@ -228,20 +229,26 @@ export const spec = { } }); // FOR PBS MODE - const seatBids = deepAccess(response, 'body.seatbid.0.bid', []); // @FIXME - seatBids.forEach(bid => { - const bidRequest = getBidRequest(bid.impid, [REQUEST.BIDDER_REQUEST]); - const pbsConfig = ID_REQUEST.pbsConfig(bidRequest.params); - if (pbsConfig.pbs) { - syncs.push({ - type: 'iframe', - url: REQUEST.PBS_SYNC_URL - .replace('$$GDPR$$', ID_UTIL.toBit(gdprConsent.gdprApplies)) - .replace('$$GDPR_CONSENT$$', gdprConsent.consentString) - , - }); - } - }) + const seatBids = deepAccess(response, 'body.seatbid', []); + if (Array.isArray(seatBids)) { + seatBids.forEach(seatbid => { + seatbid.bid.forEach(bid => { + if (bid.adm && bid.price && !bid.hasOwnProperty('errorCode')) { + const bidRequest = getBidRequest(bid.impid, REQUEST.BIDDER_REQUEST); + const pbsConfig = ID_REQUEST.pbsConfig(bidRequest.params); + if (pbsConfig.pbs) { + syncs.push({ + type: 'iframe', + url: REQUEST.PBS_SYNC_URL + .replace('$$GDPR$$', ID_UTIL.toBit(gdprConsent.gdprApplies)) + .replace('$$GDPR_CONSENT$$', gdprConsent.consentString) + , + }); + } + } + }) + }) + } }); return syncs.map(sync => { if (typeof sync === 'object' && sync.type && sync.url) { From 3f6367c7f7b4990a187882ed383754309d60da8b Mon Sep 17 00:00:00 2001 From: iosfaisal <100519197+iosfaisal@users.noreply.github.com> Date: Tue, 5 Apr 2022 15:28:28 +0600 Subject: [PATCH 03/20] PBS Test Case - Work In Progress --- .../modules/improvedigitalBidAdapter_spec.js | 69 +++++++++++++++---- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 9dcc11f5aa1..080fdc99c9d 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -7,6 +7,7 @@ import {BANNER, VIDEO} from '../../../src/mediaTypes'; describe('Improve Digital Adapter Tests', function () { const METHOD = 'POST'; const URL = 'https://ad.360yield.com/pb'; + const PBS_URL = 'https://pbs.360yield.com/openrtb2/auction'; const INSTREAM_TYPE = 1; const OUTSTREAM_TYPE = 3; @@ -238,20 +239,6 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.imp[0].ext.bidder.keyValues).to.deep.equal(keyValues); }); - // it('should add single size filter', function () { - // const bidRequest = Object.assign({}, simpleBidRequest); - // const size = { - // w: 800, - // h: 600 - // }; - // bidRequest.params.size = size; - // const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest).data); - // expect(payload.imp[0].banner).to.deep.equal(size); - // // When single size filter is set, format shouldn't be populated. This - // // is to maintain backward compatibily - // expect(payload.imp[0].banner.format).to.not.exist; - // }); - it('should add currency', function () { const bidRequest = Object.assign({}, simpleBidRequest); const getConfigStub = sinon.stub(config, 'getConfig').returns('JPY'); @@ -646,6 +633,60 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.app).does.not.exist; getConfigStub.restore(); }); + + it('should set PBS_URL when pbs mode enabled from configure', function () { + const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub.withArgs('improvedigital.pbs').returns(true); + const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; + expect(request.method).to.equal(METHOD); + expect(request.url).to.equal(PBS_URL); + expect(request.bidderRequest).to.deep.equal(bidderRequest); + const payload = JSON.parse(request.data); + expect(payload).to.be.an('object'); + expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); + getConfigStub.restore(); + }); + + it('should set PBS_URL when pbs mode enabled from params', function () { + const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + bidRequest.params.pbs = true; + const request = spec.buildRequests([bidRequest], bidderRequest)[0]; + expect(request.method).to.equal(METHOD); + expect(request.url).to.equal(PBS_URL); + expect(request.bidderRequest).to.deep.equal(bidderRequest); + const payload = JSON.parse(request.data); + expect(payload).to.be.an('object'); + expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); + }); + + it('should not set PBS_URL when pbs mode disabled from params', function () { + const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub.withArgs('improvedigital.pbs').returns(true); + const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + bidRequest.params.pbs = false; + const request = spec.buildRequests([bidRequest], bidderRequest)[0]; + expect(request.method).to.equal(METHOD); + expect(request.url).to.equal(URL); + expect(request.bidderRequest).to.deep.equal(bidderRequest); + const payload = JSON.parse(request.data); + expect(payload).to.be.an('object'); + getConfigStub.restore(); + }); + + it('should set PBS_URL when pbs mode enabled from params and disabled from config', function () { + const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub.withArgs('improvedigital.pbs').returns(false); + const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + bidRequest.params.pbs = true; + const request = spec.buildRequests([bidRequest], bidderRequest)[0]; + expect(request.method).to.equal(METHOD); + expect(request.url).to.equal(PBS_URL); + expect(request.bidderRequest).to.deep.equal(bidderRequest); + const payload = JSON.parse(request.data); + expect(payload).to.be.an('object'); + expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); + getConfigStub.restore(); + }); }); const serverResponse = { From 773fa0e281ecaaa928b23e4296b3cb7dbe0ba698 Mon Sep 17 00:00:00 2001 From: iosfaisal <100519197+iosfaisal@users.noreply.github.com> Date: Tue, 12 Apr 2022 12:18:53 +0600 Subject: [PATCH 04/20] PBS Mode Refactored - Work In Progress --- modules/improvedigitalBidAdapter.js | 108 ++++++++++++++-------------- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index e4b93f867b5..4a601684ae5 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -15,10 +15,9 @@ const REQUEST = { PB_URL: 'https://ad.360yield.com/pb', PBS_URL: 'https://pbs.360yield.com/openrtb2/auction', PBS_SYNC_URL: 'https://localhost:3001/load-cookie.html?endpoint=improvedigital&gdpr=$$GDPR$$&gdpr_consent=$$GDPR_CONSENT$$', - getUrl(pbs = false) { - return pbs ? this.PBS_URL : this.PB_URL; + getUrl(pbsMode = false) { + return pbsMode ? this.PBS_URL : this.PB_URL; }, - BIDDER_REQUEST: [], }; const VIDEO_PARAMS = { @@ -66,6 +65,7 @@ export const spec = { gvlid: 253, aliases: ['id'], supportedMediaTypes: [BANNER, NATIVE, VIDEO], + syncStore: { pbsMode: false }, /** * Determines whether or not the given bid request is valid. @@ -155,8 +155,6 @@ export const spec = { deepSetValue(request, 'user.ext.eids', eids.length ? eids : undefined); } - REQUEST.BIDDER_REQUEST.push(bidderRequest); - return ID_REQUEST.buildServerRequests(request, bidRequests, bidderRequest); }, @@ -182,18 +180,18 @@ export const spec = { return; } const bidRequest = getBidRequest(bidObject.impid, [bidderRequest]); - const idExt = deepAccess(bidObject, `ext.${BIDDER_CODE}`); + const idExt = deepAccess(bidObject, `ext.${BIDDER_CODE}`, {}); const bid = { requestId: bidObject.impid, cpm: bidObject.price, creativeId: bidObject.crid, currency: serverResponse.body.cur.toUpperCase() || 'USD', - dealId: (idExt && typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined, + dealId: (typeof idExt.buying_type === 'string' && idExt.buying_type !== 'rtb') ? idExt.line_item_id : undefined, meta: { advertiserDomains: bidObject.adomain ? bidObject.adomain : [] }, - netRevenue: idExt && idExt.is_net || false, + netRevenue: idExt.is_net || false, ttl: CREATIVE_TTL } @@ -219,8 +217,19 @@ export const spec = { * @return {UserSync[]} The user syncs which should be dropped. */ getUserSyncs(syncOptions, serverResponses, gdprConsent) { - if (syncOptions.pixelEnabled) { - const syncs = []; + const syncs = []; + + if (this.syncStore.pbsMode && syncOptions.iframeEnabled) { + // FOR PBS MODE + syncs.push({ + type: 'iframe', + url: REQUEST.PBS_SYNC_URL + .replace('$$GDPR$$', ID_UTIL.toBit(gdprConsent.gdprApplies)) + .replace('$$GDPR_CONSENT$$', gdprConsent.consentString) + , + }); + } + else if (syncOptions.pixelEnabled) { serverResponses.forEach(response => { const syncArr = deepAccess(response, `body.ext.${BIDDER_CODE}.sync`, []); syncArr.forEach(syncElement => { @@ -228,39 +237,18 @@ export const spec = { syncs.push(syncElement); } }); - // FOR PBS MODE - const seatBids = deepAccess(response, 'body.seatbid', []); - if (Array.isArray(seatBids)) { - seatBids.forEach(seatbid => { - seatbid.bid.forEach(bid => { - if (bid.adm && bid.price && !bid.hasOwnProperty('errorCode')) { - const bidRequest = getBidRequest(bid.impid, REQUEST.BIDDER_REQUEST); - const pbsConfig = ID_REQUEST.pbsConfig(bidRequest.params); - if (pbsConfig.pbs) { - syncs.push({ - type: 'iframe', - url: REQUEST.PBS_SYNC_URL - .replace('$$GDPR$$', ID_UTIL.toBit(gdprConsent.gdprApplies)) - .replace('$$GDPR_CONSENT$$', gdprConsent.consentString) - , - }); - } - } - }) - }) - } - }); - return syncs.map(sync => { - if (typeof sync === 'object' && sync.type && sync.url) { - return { - type: sync.type, - url: sync.url, - } - } - return { type: 'image', url: sync } }); } - return []; + + return syncs.map(sync => { + if (typeof sync === 'object' && sync.type && sync.url) { + return { + type: sync.type, + url: sync.url, + } + } + return { type: 'image', url: sync } + }); } }; @@ -270,40 +258,48 @@ const ID_REQUEST = { buildServerRequests(requestObject, bidRequests, bidderRequest) { const requests = []; if (config.getConfig('improvedigital.singleRequest') === true) { - const pbsConfig = this.pbsConfig(); - requestObject.imp = bidRequests.map((bidRequest) => this.buildImp(bidRequest, pbsConfig)); - requests[0] = this.formatRequest(requestObject, bidderRequest, pbsConfig); + const pbsModeEnabled = this.isPBSModeEnabled(); + requestObject.imp = bidRequests.map((bidRequest) => this.buildImp(bidRequest, pbsModeEnabled)); + requests[0] = this.formatRequest(requestObject, bidderRequest, pbsModeEnabled); } else { bidRequests.map((bidRequest) => { const request = deepClone(requestObject); - const pbsConfig = this.pbsConfig(bidRequest.params); + const pbsModeEnabled = this.isPBSModeEnabled(bidRequest.params); request.id = bidRequest.bidId || getUniqueIdentifierStr(); - request.imp = [this.buildImp(bidRequest, pbsConfig)]; + request.imp = [this.buildImp(bidRequest, pbsModeEnabled)]; deepSetValue(request, 'source.tid', bidRequest.transactionId); - requests.push(this.formatRequest(request, bidderRequest, pbsConfig)); + requests.push(this.formatRequest(request, bidderRequest, pbsModeEnabled)); }); } return requests; }, - formatRequest(request, bidderRequest, pbsConfig) { + formatRequest(request, bidderRequest, pbsMode) { return { method: 'POST', - url: REQUEST.getUrl(pbsConfig.pbs), + url: REQUEST.getUrl(pbsMode), data: JSON.stringify(request), bidderRequest } }, - pbsConfig(bidParams = {}) { - return mergeDeep({}, { - pbs: config.getConfig('improvedigital.pbs') === true, - }, bidParams) + isPBSModeEnabled(bidParams = {}) { + let pbsMode = config.getConfig('improvedigital.pbs') === true; + + if (typeof bidParams.pbs === 'boolean') { + pbsMode = bidParams.pbs === true; + } + + if (pbsMode === true) { + spec.syncStore.pbsMode = true; + } + + return pbsMode; }, - buildImp(bidRequest, pbsConfig) { - const bidderCode = pbsConfig.pbs ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; + buildImp(bidRequest, pbsMode) { + const bidderCode = pbsMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; const imp = { id: getBidIdParameter('bidId', bidRequest) || getUniqueIdentifierStr(), secure: ID_UTIL.toBit(window.location.protocol === 'https:'), @@ -321,7 +317,7 @@ const ID_REQUEST = { if (placementId) { deepSetValue(imp, bidderCode + '.placementId', placementId); // When PBS Mode Enabled - if (pbsConfig.pbs) { + if (pbsMode) { deepSetValue(imp, 'ext.prebid.storedrequest.id', placementId); } } else { From 9a43468a2dffe1dcbb0832e6e53b8e78c749a540 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Wed, 27 Apr 2022 17:33:46 +0200 Subject: [PATCH 05/20] Misc changes --- modules/improvedigitalBidAdapter.js | 87 ++++++++++++++++------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 4a601684ae5..fcb9ba8d075 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -11,14 +11,9 @@ import {createEidsArray} from './userId/eids.js'; const BIDDER_CODE = 'improvedigital'; const CREATIVE_TTL = 300; -const REQUEST = { - PB_URL: 'https://ad.360yield.com/pb', - PBS_URL: 'https://pbs.360yield.com/openrtb2/auction', - PBS_SYNC_URL: 'https://localhost:3001/load-cookie.html?endpoint=improvedigital&gdpr=$$GDPR$$&gdpr_consent=$$GDPR_CONSENT$$', - getUrl(pbsMode = false) { - return pbsMode ? this.PBS_URL : this.PB_URL; - }, -}; +const AD_SERVER_URL = 'https://ad.360yield.com/pb'; +const PBS_URL = 'https://pbs.360yield.com/openrtb2/auction'; +const IFRAME_SYNC_URL = 'https://hb.360yield.com/prebid-universal-creative/load-cookie.html'; const VIDEO_PARAMS = { DEFAULT_MIMES: ['video/mp4'], @@ -65,7 +60,7 @@ export const spec = { gvlid: 253, aliases: ['id'], supportedMediaTypes: [BANNER, NATIVE, VIDEO], - syncStore: { pbsMode: false }, + syncStore: { pbsMode: false, placementId: null }, /** * Determines whether or not the given bid request is valid. @@ -150,6 +145,9 @@ export const spec = { deepSetValue(request, 'source.ext.schain', bidRequest0.schain); deepSetValue(request, 'source.tid', bidRequest0.transactionId); + // Save a placement id to send it to the ad server when fetching the user syncs + this.syncStore.placementId = this.syncStore.placementId || bidRequest0.params.placementId; + if (bidRequest0.userId) { const eids = createEidsArray(bidRequest0.userId); deepSetValue(request, 'user.ext.eids', eids.length ? eids : undefined); @@ -219,17 +217,17 @@ export const spec = { getUserSyncs(syncOptions, serverResponses, gdprConsent) { const syncs = []; - if (this.syncStore.pbsMode && syncOptions.iframeEnabled) { - // FOR PBS MODE + if ((this.syncStore.pbsMode || !syncOptions.pixelEnabled) && syncOptions.iframeEnabled) { + const { gdprApplies, consentString } = gdprConsent || {}; syncs.push({ type: 'iframe', - url: REQUEST.PBS_SYNC_URL - .replace('$$GDPR$$', ID_UTIL.toBit(gdprConsent.gdprApplies)) - .replace('$$GDPR_CONSENT$$', gdprConsent.consentString) - , + url: IFRAME_SYNC_URL + + `?pid=${this.syncStore.placementId}` + + this.syncStore.pbsMode ? '&pbs=1' : '' + + typeof gdprApplies !== 'undefined' ? `&gdpr=${ID_UTIL.toBit(gdprApplies)}` : '' + + consentString ? `&gdpr_consent=${consentString}` : '' }); - } - else if (syncOptions.pixelEnabled) { + } else if (syncOptions.pixelEnabled) { serverResponses.forEach(response => { const syncArr = deepAccess(response, `body.ext.${BIDDER_CODE}.sync`, []); syncArr.forEach(syncElement => { @@ -256,15 +254,31 @@ registerBidder(spec); const ID_REQUEST = { buildServerRequests(requestObject, bidRequests, bidderRequest) { + const globalPbsMode = config.getConfig('improvedigital.pbs') === true; const requests = []; if (config.getConfig('improvedigital.singleRequest') === true) { - const pbsModeEnabled = this.isPBSModeEnabled(); - requestObject.imp = bidRequests.map((bidRequest) => this.buildImp(bidRequest, pbsModeEnabled)); - requests[0] = this.formatRequest(requestObject, bidderRequest, pbsModeEnabled); + // Split imps between those going to the ad server and those going to PBS + const pbsImps = []; + const nonPbsImps = []; + bidRequests.map((bidRequest) => { + const pbsModeEnabled = this.isPbsModeEnabled(globalPbsMode, bidRequest.params); + const imp = this.buildImp(bidRequest, pbsModeEnabled) + pbsModeEnabled ? pbsImps.push(imp) : nonPbsImps.push(imp); + }); + if (pbsImps.length) { + const request = deepClone(requestObject); + request.imp = pbsImps; + requests.push(this.formatRequest(request, bidderRequest, true)); + } + if (nonPbsImps.length) { + const request = deepClone(requestObject); + request.imp = nonPbsImps; + requests.push(this.formatRequest(request, bidderRequest, false)); + } } else { bidRequests.map((bidRequest) => { const request = deepClone(requestObject); - const pbsModeEnabled = this.isPBSModeEnabled(bidRequest.params); + const pbsModeEnabled = this.isPbsModeEnabled(globalPbsMode, bidRequest.params); request.id = bidRequest.bidId || getUniqueIdentifierStr(); request.imp = [this.buildImp(bidRequest, pbsModeEnabled)]; deepSetValue(request, 'source.tid', bidRequest.transactionId); @@ -278,28 +292,21 @@ const ID_REQUEST = { formatRequest(request, bidderRequest, pbsMode) { return { method: 'POST', - url: REQUEST.getUrl(pbsMode), + url: pbsMode ? PBS_URL : AD_SERVER_URL, data: JSON.stringify(request), bidderRequest } }, - isPBSModeEnabled(bidParams = {}) { - let pbsMode = config.getConfig('improvedigital.pbs') === true; - - if (typeof bidParams.pbs === 'boolean') { - pbsMode = bidParams.pbs === true; - } - - if (pbsMode === true) { + isPbsModeEnabled(globalPbsMode, bidParams) { + const pbsMode = typeof bidParams.pbs === 'boolean' ? bidParams.pbs : globalPbsMode; + if (pbsMode && !spec.syncStore.pbsMode) { spec.syncStore.pbsMode = true; } - return pbsMode; }, buildImp(bidRequest, pbsMode) { - const bidderCode = pbsMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; const imp = { id: getBidIdParameter('bidId', bidRequest) || getUniqueIdentifierStr(), secure: ID_UTIL.toBit(window.location.protocol === 'https:'), @@ -313,19 +320,19 @@ const ID_REQUEST = { deepSetValue(imp, 'bidfloorcur', bidFloorCur ? bidFloorCur.toUpperCase() : undefined); } + const bidderParamsPath = pbsMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; const placementId = getBidIdParameter('placementId', bidRequest.params); if (placementId) { - deepSetValue(imp, bidderCode + '.placementId', placementId); - // When PBS Mode Enabled + deepSetValue(imp, `${bidderParamsPath}.placementId`, placementId); if (pbsMode) { - deepSetValue(imp, 'ext.prebid.storedrequest.id', placementId); + deepSetValue(imp, 'ext.prebid.storedrequest.id', '' + placementId); } } else { - deepSetValue(imp, bidderCode + '.publisherId', getBidIdParameter('publisherId', bidRequest.params)); - deepSetValue(imp, bidderCode + '.placementKey', getBidIdParameter('placementKey', bidRequest.params)); + deepSetValue(imp, `${bidderParamsPath}.publisherId`, getBidIdParameter('publisherId', bidRequest.params)); + deepSetValue(imp, `${bidderParamsPath}.placementKey`, getBidIdParameter('placementKey', bidRequest.params)); } - deepSetValue(imp, bidderCode + '.keyValues', getBidIdParameter('keyValues', bidRequest.params) || undefined); + deepSetValue(imp, `${bidderParamsPath}.keyValues`, getBidIdParameter('keyValues', bidRequest.params) || undefined); // Adding GPID const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid') || @@ -494,9 +501,9 @@ const ID_RESPONSE = { this.buildNativeAd(bid, bidRequest, bidResponse) } } else { - if (bidResponse.adm.search(/^ Date: Fri, 29 Apr 2022 15:43:36 +0200 Subject: [PATCH 06/20] tmax & addtl consent improvements --- modules/improvedigitalBidAdapter.js | 16 ++++++---- .../modules/improvedigitalBidAdapter_spec.js | 32 ++++++++++++++++--- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index c696dabc64a..d1c35f63f9a 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -117,16 +117,20 @@ export const spec = { if (additionalConsent && additionalConsent.indexOf('~') !== -1) { // Google Ad Tech Provider IDs const atpIds = additionalConsent.substring(additionalConsent.indexOf('~') + 1); - deepSetValue( - request, - 'user.ext.consented_providers_settings.consented_providers', - atpIds.split('.').map(id => parseInt(id, 10)) - ); + if (atpIds) { + deepSetValue( + request, + 'user.ext.consented_providers_settings.consented_providers', + atpIds.split('.').map(id => parseInt(id, 10)) + ); + } } } // Timeout - deepSetValue(request, 'tmax', bidderRequest.timeout); + if (bidderRequest.timeout) { + request.tmax = parseInt(bidderRequest.timeout); + } // US Privacy if (typeof bidderRequest.uspConsent !== typeof undefined) { deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent); diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 9dcc11f5aa1..d721c2d20bc 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { spec } from 'modules/improvedigitalBidAdapter.js'; import { config } from 'src/config.js'; -import * as utils from 'src/utils.js'; +import { deepClone } from 'src/utils.js'; import {BANNER, VIDEO} from '../../../src/mediaTypes'; describe('Improve Digital Adapter Tests', function () { @@ -34,7 +34,7 @@ describe('Improve Digital Adapter Tests', function () { skipafter: 30 } - const instreamBidRequest = utils.deepClone(simpleBidRequest); + const instreamBidRequest = deepClone(simpleBidRequest); instreamBidRequest.mediaTypes = { video: { context: 'instream', @@ -42,7 +42,7 @@ describe('Improve Digital Adapter Tests', function () { } }; - const outstreamBidRequest = utils.deepClone(simpleBidRequest); + const outstreamBidRequest = deepClone(simpleBidRequest); outstreamBidRequest.mediaTypes = { video: { context: 'outstream', @@ -50,7 +50,7 @@ describe('Improve Digital Adapter Tests', function () { } }; - const multiFormatBidRequest = utils.deepClone(simpleBidRequest); + const multiFormatBidRequest = deepClone(simpleBidRequest); multiFormatBidRequest.mediaTypes = { banner: { sizes: [[300, 250], [160, 600]] @@ -294,6 +294,14 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.user.ext.consented_providers_settings.consented_providers).to.exist.and.to.deep.equal([1, 35, 41, 101]); }); + it('should not add consented providers when empty', function () { + const bidderRequestGdprEmptyAddtl = deepClone(bidderRequestGdpr); + bidderRequestGdprEmptyAddtl.gdprConsent.addtlConsent = '1~'; + const bidRequest = Object.assign({}, simpleBidRequest); + const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequestGdprEmptyAddtl)[0].data); + expect(payload.user.ext.consented_providers_settings).to.not.exist; + }); + it('should add CCPA consent string', function () { const bidRequest = Object.assign({}, simpleBidRequest); const request = spec.buildRequests([bidRequest], {...bidderRequest, ...{ uspConsent: '1YYY' }}); @@ -308,6 +316,20 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.site.page).to.equal('https://blah.com/test.html'); }); + it('should add timeout', function () { + const bidderRequestTimeout = deepClone(bidderRequest); + // Int + bidderRequestTimeout.timeout = 300; + const bidRequest = Object.assign({}, simpleBidRequest); + let request = spec.buildRequests([bidRequest], bidderRequestTimeout)[0]; + expect(JSON.parse(request.data).tmax).to.equal(300); + + // String + bidderRequestTimeout.timeout = '500'; + request = spec.buildRequests([bidRequest], bidderRequestTimeout)[0]; + expect(JSON.parse(request.data).tmax).to.equal(500); + }); + it('should not add video params for banner', function () { const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); bidRequest.params.video = videoParams; @@ -916,7 +938,7 @@ describe('Improve Digital Adapter Tests', function () { } ]; - const expectedBidOutstreamVideo = utils.deepClone(expectedBidInstreamVideo); + const expectedBidOutstreamVideo = deepClone(expectedBidInstreamVideo); expectedBidOutstreamVideo[0].adResponse = { content: expectedBidOutstreamVideo[0].vastXml }; From 9ef6c8b446c1ba5301d82b80f57009203ede21be Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Mon, 2 May 2022 11:35:09 +0200 Subject: [PATCH 07/20] fixes --- modules/improvedigitalBidAdapter.js | 15 +++-- .../modules/improvedigitalBidAdapter_spec.js | 57 +++++++++---------- 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index fcb9ba8d075..af4d17c4122 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -90,8 +90,7 @@ export const spec = { version: '$prebid.version$', } } - }, - test: 1 + } }; // Device @@ -218,14 +217,14 @@ export const spec = { const syncs = []; if ((this.syncStore.pbsMode || !syncOptions.pixelEnabled) && syncOptions.iframeEnabled) { - const { gdprApplies, consentString } = gdprConsent || {}; + const { gdprApplies, consentString } = gdprConsent || {}; syncs.push({ type: 'iframe', - url: IFRAME_SYNC_URL - + `?pid=${this.syncStore.placementId}` - + this.syncStore.pbsMode ? '&pbs=1' : '' - + typeof gdprApplies !== 'undefined' ? `&gdpr=${ID_UTIL.toBit(gdprApplies)}` : '' - + consentString ? `&gdpr_consent=${consentString}` : '' + url: IFRAME_SYNC_URL + + `?pid=${this.syncStore.placementId}` + + (this.syncStore.pbsMode ? '&pbs=1' : '') + + (typeof gdprApplies !== 'undefined' ? `&gdpr=${ID_UTIL.toBit(gdprApplies)}` : '') + + (consentString ? `&gdpr_consent=${consentString}` : '') }); } else if (syncOptions.pixelEnabled) { serverResponses.forEach(response => { diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 080fdc99c9d..579df83a8a0 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -1,12 +1,12 @@ import { expect } from 'chai'; import { spec } from 'modules/improvedigitalBidAdapter.js'; import { config } from 'src/config.js'; -import * as utils from 'src/utils.js'; +import { deepClone } from 'src/utils.js'; import {BANNER, VIDEO} from '../../../src/mediaTypes'; describe('Improve Digital Adapter Tests', function () { const METHOD = 'POST'; - const URL = 'https://ad.360yield.com/pb'; + const AD_SERVER_URL = 'https://ad.360yield.com/pb'; const PBS_URL = 'https://pbs.360yield.com/openrtb2/auction'; const INSTREAM_TYPE = 1; const OUTSTREAM_TYPE = 3; @@ -35,7 +35,7 @@ describe('Improve Digital Adapter Tests', function () { skipafter: 30 } - const instreamBidRequest = utils.deepClone(simpleBidRequest); + const instreamBidRequest = deepClone(simpleBidRequest); instreamBidRequest.mediaTypes = { video: { context: 'instream', @@ -43,7 +43,7 @@ describe('Improve Digital Adapter Tests', function () { } }; - const outstreamBidRequest = utils.deepClone(simpleBidRequest); + const outstreamBidRequest = deepClone(simpleBidRequest); outstreamBidRequest.mediaTypes = { video: { context: 'outstream', @@ -51,7 +51,7 @@ describe('Improve Digital Adapter Tests', function () { } }; - const multiFormatBidRequest = utils.deepClone(simpleBidRequest); + const multiFormatBidRequest = deepClone(simpleBidRequest); multiFormatBidRequest.mediaTypes = { banner: { sizes: [[300, 250], [160, 600]] @@ -151,7 +151,7 @@ describe('Improve Digital Adapter Tests', function () { const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; expect(request).to.be.an('object'); expect(request.method).to.equal(METHOD); - expect(request.url).to.equal(URL); + expect(request.url).to.equal(AD_SERVER_URL); expect(request.bidderRequest).to.deep.equal(bidderRequest); const payload = JSON.parse(request.data); @@ -190,7 +190,7 @@ describe('Improve Digital Adapter Tests', function () { const request = spec.buildRequests([multiFormatBidRequest], multiFormatBidderRequest)[0]; expect(request).to.be.an('object'); expect(request.method).to.equal(METHOD); - expect(request.url).to.equal(URL); + expect(request.url).to.equal(AD_SERVER_URL); expect(request.bidderRequest).to.deep.equal(multiFormatBidderRequest); const payload = JSON.parse(request.data); @@ -296,7 +296,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should not add video params for banner', function () { - const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + const bidRequest = deepClone(simpleBidRequest); bidRequest.params.video = videoParams; const request = spec.buildRequests([bidRequest], bidderRequest)[0]; const payload = JSON.parse(request.data); @@ -304,11 +304,11 @@ describe('Improve Digital Adapter Tests', function () { }); it('should add correct placement value for instream and outstream video', function () { - let bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + let bidRequest = deepClone(simpleBidRequest); let payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest)[0].data); expect(payload.imp[0].video).to.not.exist; - bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + bidRequest = deepClone(simpleBidRequest); bidRequest.mediaTypes = { video: { context: 'instream', @@ -323,7 +323,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set video params for instream', function() { - const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest)); + const bidRequest = deepClone(instreamBidRequest); delete bidRequest.mediaTypes.video.playerSize; const videoParams = { mimes: ['video/mp4'], @@ -346,7 +346,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set video playerSize over video params', () => { - const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest)); + const bidRequest = deepClone(instreamBidRequest); bidRequest.params.video = { w: 1024, h: 640 } @@ -357,7 +357,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set skip params only if skip=1', function() { - const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest)); + const bidRequest = deepClone(instreamBidRequest); // 1 const videoTest = { skip: 1, @@ -391,7 +391,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should ignore invalid/unexpected video params', function() { - const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest)); + const bidRequest = deepClone(instreamBidRequest); // 1 const videoTest = { skip: 1, @@ -407,7 +407,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set video params for outstream', function() { - const bidRequest = JSON.parse(JSON.stringify(outstreamBidRequest)); + const bidRequest = deepClone(outstreamBidRequest); bidRequest.params.video = videoParams; const request = spec.buildRequests([bidRequest])[0]; const payload = JSON.parse(request.data); @@ -421,7 +421,7 @@ describe('Improve Digital Adapter Tests', function () { }); // it('should set video params for multi-format', function() { - const bidRequest = JSON.parse(JSON.stringify(multiFormatBidRequest)); + const bidRequest = deepClone(multiFormatBidRequest); bidRequest.params.video = videoParams; const request = spec.buildRequests([bidRequest])[0]; const payload = JSON.parse(request.data); @@ -638,7 +638,6 @@ describe('Improve Digital Adapter Tests', function () { const getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.pbs').returns(true); const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; - expect(request.method).to.equal(METHOD); expect(request.url).to.equal(PBS_URL); expect(request.bidderRequest).to.deep.equal(bidderRequest); const payload = JSON.parse(request.data); @@ -648,7 +647,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set PBS_URL when pbs mode enabled from params', function () { - const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + const bidRequest = deepClone(simpleBidRequest); bidRequest.params.pbs = true; const request = spec.buildRequests([bidRequest], bidderRequest)[0]; expect(request.method).to.equal(METHOD); @@ -662,7 +661,7 @@ describe('Improve Digital Adapter Tests', function () { it('should not set PBS_URL when pbs mode disabled from params', function () { const getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.pbs').returns(true); - const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + const bidRequest = deepClone(simpleBidRequest); bidRequest.params.pbs = false; const request = spec.buildRequests([bidRequest], bidderRequest)[0]; expect(request.method).to.equal(METHOD); @@ -676,7 +675,7 @@ describe('Improve Digital Adapter Tests', function () { it('should set PBS_URL when pbs mode enabled from params and disabled from config', function () { const getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.pbs').returns(false); - const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); + const bidRequest = deepClone(simpleBidRequest); bidRequest.params.pbs = true; const request = spec.buildRequests([bidRequest], bidderRequest)[0]; expect(request.method).to.equal(METHOD); @@ -957,7 +956,7 @@ describe('Improve Digital Adapter Tests', function () { } ]; - const expectedBidOutstreamVideo = utils.deepClone(expectedBidInstreamVideo); + const expectedBidOutstreamVideo = deepClone(expectedBidInstreamVideo); expectedBidOutstreamVideo[0].adResponse = { content: expectedBidOutstreamVideo[0].vastXml }; @@ -978,7 +977,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set dealId correctly', function () { - const response = JSON.parse(JSON.stringify(serverResponse)); + const response = deepClone(serverResponse); let bids; delete response.body.seatbid[0].bid[0].ext.improvedigital.line_item_id; @@ -1008,14 +1007,14 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set currency', function () { - const response = JSON.parse(JSON.stringify(serverResponse)); + const response = deepClone(serverResponse); response.body.cur = 'eur'; const bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].currency).to.equal('EUR'); }); it('should return empty array for bad response or no price', function () { - let response = JSON.parse(JSON.stringify(serverResponse)); + let response = deepClone(serverResponse); let bids; // Price missing or 0 @@ -1030,13 +1029,13 @@ describe('Improve Digital Adapter Tests', function () { expect(bids).to.deep.equal([]); // errorCode present - response = JSON.parse(JSON.stringify(serverResponse)); + response = deepClone(serverResponse); response.body.seatbid[0].bid[0].errorCode = undefined; bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); // adm and native missing - response = JSON.parse(JSON.stringify(serverResponse)); + response = deepClone(serverResponse); delete response.body.seatbid[0].bid[0].adm; bids = spec.interpretResponse(response, {bidderRequest}); expect(bids).to.deep.equal([]); @@ -1046,7 +1045,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should set netRevenue', function () { - const response = JSON.parse(JSON.stringify(serverResponse)); + const response = deepClone(serverResponse); response.body.seatbid[0].bid[0].ext.improvedigital.is_net = true; const bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].netRevenue).to.equal(true); @@ -1054,7 +1053,7 @@ describe('Improve Digital Adapter Tests', function () { it('should set advertiserDomains', function () { const adomain = ['domain.com']; - const response = JSON.parse(JSON.stringify(serverResponse)); + const response = deepClone(serverResponse); response.body.seatbid[0].bid[0].adomain = adomain; const bids = spec.interpretResponse(response, {bidderRequest}); expect(bids[0].meta.advertiserDomains).to.equal(adomain); @@ -1062,7 +1061,7 @@ describe('Improve Digital Adapter Tests', function () { // // Native ads it('should return a well-formed native ad bid', function () { - const nativeBidderRequest = JSON.parse(JSON.stringify(bidderRequest)); + const nativeBidderRequest = deepClone(bidderRequest); nativeBidderRequest.bids[0].bidId = '2d7a7db325c6f'; delete nativeBidderRequest.bids[0].mediaTypes.banner; nativeBidderRequest.bids[0].mediaTypes.native = {}; From 030e1e2ac1b9164172cb307907e71526fb514273 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Mon, 2 May 2022 16:51:28 +0200 Subject: [PATCH 08/20] PBS mode unit tests --- .../modules/improvedigitalBidAdapter_spec.js | 79 +++++++++---------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 79e2766f829..17535fcad2d 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -35,15 +35,25 @@ describe('Improve Digital Adapter Tests', function () { skipafter: 30 } - const instreamBidRequest = deepClone(simpleBidRequest); - instreamBidRequest.mediaTypes = { - video: { - context: 'instream', - playerSize: [640, 480] + const instreamBidRequest = { + bidder: 'improvedigital', + params: { + placementId: 123456 + }, + adUnitCode: 'video1', + transactionId: 'vf183e871-fbed-45f0-a427-c8a63c4c01eb', + bidId: '33e9500b21129f', + bidderRequestId: 'v2772c1e566670b', + auctionId: 'v192721e36a0239', + mediaTypes: { + video: { + context: 'instream', + playerSize: [640, 480] + } } }; - const outstreamBidRequest = deepClone(simpleBidRequest); + const outstreamBidRequest = deepClone(instreamBidRequest); outstreamBidRequest.mediaTypes = { video: { context: 'outstream', @@ -656,56 +666,43 @@ describe('Improve Digital Adapter Tests', function () { getConfigStub.restore(); }); - it('should set PBS_URL when pbs mode enabled from configure', function () { + it('should set pbs url when pbs mode enabled from global configuration', function () { const getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.pbs').returns(true); const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; + expect(request.method).to.equal(METHOD); expect(request.url).to.equal(PBS_URL); - expect(request.bidderRequest).to.deep.equal(bidderRequest); - const payload = JSON.parse(request.data); - expect(payload).to.be.an('object'); - expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); getConfigStub.restore(); }); - it('should set PBS_URL when pbs mode enabled from params', function () { + // expect(request.bidderRequest).to.deep.equal(bidderRequest); + // const payload = JSON.parse(request.data); + // expect(payload).to.be.an('object'); + // expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); + + it('should set pbs url when pbs mode enabled in adunit params', function () { const bidRequest = deepClone(simpleBidRequest); bidRequest.params.pbs = true; - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - expect(request.method).to.equal(METHOD); + let request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; expect(request.url).to.equal(PBS_URL); - expect(request.bidderRequest).to.deep.equal(bidderRequest); - const payload = JSON.parse(request.data); - expect(payload).to.be.an('object'); - expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); - }); - it('should not set PBS_URL when pbs mode disabled from params', function () { const getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.pbs').returns(true); - const bidRequest = deepClone(simpleBidRequest); - bidRequest.params.pbs = false; - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - expect(request.method).to.equal(METHOD); - expect(request.url).to.equal(URL); - expect(request.bidderRequest).to.deep.equal(bidderRequest); - const payload = JSON.parse(request.data); - expect(payload).to.be.an('object'); - getConfigStub.restore(); - }); - it('should set PBS_URL when pbs mode enabled from params and disabled from config', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + // adunit param takes precedence over the global config getConfigStub.withArgs('improvedigital.pbs').returns(false); - const bidRequest = deepClone(simpleBidRequest); - bidRequest.params.pbs = true; - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - expect(request.method).to.equal(METHOD); + request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; expect(request.url).to.equal(PBS_URL); - expect(request.bidderRequest).to.deep.equal(bidderRequest); - const payload = JSON.parse(request.data); - expect(payload).to.be.an('object'); - expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); + + bidRequest.params.pbs = false; + getConfigStub.withArgs('improvedigital.pbs').returns(true); + request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; + expect(request.url).to.equal(AD_SERVER_URL); + + const requests = spec.buildRequests([bidRequest, instreamBidRequest], { bids: [bidRequest, instreamBidRequest] }); + expect(requests.length).to.equal(2); + expect(requests[0].url).to.equal(AD_SERVER_URL); + expect(requests[1].url).to.equal(PBS_URL); + getConfigStub.restore(); }); }); From a22e792fc9efee5a19c35e73933889cca206f247 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Tue, 3 May 2022 12:28:46 +0200 Subject: [PATCH 09/20] user syncs changes + tests --- modules/improvedigitalBidAdapter.js | 18 +-- .../modules/improvedigitalBidAdapter_spec.js | 109 ++++++++++++++---- 2 files changed, 93 insertions(+), 34 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 612607caf8a..1fb05335589 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -225,7 +225,7 @@ export const spec = { syncs.push({ type: 'iframe', url: IFRAME_SYNC_URL + - `?pid=${this.syncStore.placementId}` + + `?placement_id=${this.syncStore.placementId}` + (this.syncStore.pbsMode ? '&pbs=1' : '') + (typeof gdprApplies !== 'undefined' ? `&gdpr=${ID_UTIL.toBit(gdprApplies)}` : '') + (consentString ? `&gdpr_consent=${consentString}` : '') @@ -233,23 +233,15 @@ export const spec = { } else if (syncOptions.pixelEnabled) { serverResponses.forEach(response => { const syncArr = deepAccess(response, `body.ext.${BIDDER_CODE}.sync`, []); - syncArr.forEach(syncElement => { - if (syncs.indexOf(syncElement) === -1) { - syncs.push(syncElement); + syncArr.forEach(url => { + if (!syncs.some(sync => sync.url === url)) { + syncs.push({ type: 'image', url }); } }); }); } - return syncs.map(sync => { - if (typeof sync === 'object' && sync.type && sync.url) { - return { - type: sync.type, - url: sync.url, - } - } - return { type: 'image', url: sync } - }); + return syncs; } }; diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 17535fcad2d..92339153ae5 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -8,6 +8,7 @@ describe('Improve Digital Adapter Tests', function () { const METHOD = 'POST'; const AD_SERVER_URL = 'https://ad.360yield.com/pb'; const PBS_URL = 'https://pbs.360yield.com/openrtb2/auction'; + const IFRAME_SYNC_URL = 'https://hb.360yield.com/prebid-universal-creative/load-cookie.html'; const INSTREAM_TYPE = 1; const OUTSTREAM_TYPE = 3; @@ -29,6 +30,9 @@ describe('Improve Digital Adapter Tests', function () { sizes: [[300, 250], [160, 600]] }; + const pbsBidRequest = deepClone(simpleBidRequest); + pbsBidRequest.params.pbs = true; + const videoParams = { skip: 1, skipmin: 5, @@ -86,6 +90,10 @@ describe('Improve Digital Adapter Tests', function () { bids: [simpleBidRequest] }; + const pbsBidderRequest = { + bids: [pbsBidRequest] + }; + const instreamBidderRequest = { bids: [instreamBidRequest] }; @@ -98,14 +106,16 @@ describe('Improve Digital Adapter Tests', function () { bids: [multiFormatBidRequest] }; + const gdprConsent = { + consentString: 'CONSENT', + vendorData: {}, + gdprApplies: true, + addtlConsent: '1~1.35.41.101', + }; + const bidderRequestGdpr = { bids: [simpleBidRequest], - gdprConsent: { - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {}, - gdprApplies: true, - addtlConsent: '1~1.35.41.101', - }, + gdprConsent }; const bidderRequestReferrer = { @@ -287,7 +297,7 @@ describe('Improve Digital Adapter Tests', function () { const bidRequest = Object.assign({}, simpleBidRequest); const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequestGdpr)[0].data); expect(payload.regs.ext.gdpr).to.exist.and.to.equal(1); - expect(payload.user.ext.consent).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); + expect(payload.user.ext.consent).to.equal('CONSENT'); expect(payload.user.ext.consented_providers_settings.consented_providers).to.exist.and.to.deep.equal([1, 35, 41, 101]); }); @@ -681,8 +691,7 @@ describe('Improve Digital Adapter Tests', function () { // expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); it('should set pbs url when pbs mode enabled in adunit params', function () { - const bidRequest = deepClone(simpleBidRequest); - bidRequest.params.pbs = true; + const bidRequest = deepClone(pbsBidRequest); let request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; expect(request.url).to.equal(PBS_URL); @@ -737,7 +746,16 @@ describe('Improve Digital Adapter Tests', function () { ], 'seat': 'improvedigital' } - ] + ], + ext: { + improvedigital: { + sync: [ + 'https://link1', + 'https://link2', + 'https://link3', + ] + } + } } }; @@ -797,7 +815,7 @@ describe('Improve Digital Adapter Tests', function () { sync: [ 'https://link1', 'https://link2', - 'https://link3', + 'https://link4', ] } } @@ -1132,21 +1150,70 @@ describe('Improve Digital Adapter Tests', function () { }); describe('getUserSyncs', function () { - const serverResponses = [ serverResponseTwoBids ]; + const serverResponses = [ serverResponse, serverResponseTwoBids ]; + const pixelSyncs = [ + { type: 'image', url: 'https://link1' }, + { type: 'image', url: 'https://link2' }, + { type: 'image', url: 'https://link3' }, + { type: 'image', url: 'https://link4' } + ]; + + const basicIframeSyncUrl = `${IFRAME_SYNC_URL}?placement_id=1053688`; - it('should return no syncs when pixel syncing is disabled', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: false }, serverResponses); + this.beforeEach(function () { + spec.syncStore = { pbsMode: false, placementId: null }; + }); + + it('should return no syncs when neither iframe nor pixel syncing is enabled', function () { + const syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }, serverResponses); expect(syncs).to.deep.equal([]); }); - it('should return user syncs', function () { + it('should return pixel user syncs for the ad server mode', function () { const syncs = spec.getUserSyncs({ pixelEnabled: true }, serverResponses); - const expected = [ - { type: 'image', url: 'https://link1' }, - { type: 'image', url: 'https://link2' }, - { type: 'image', url: 'https://link3' } - ]; - expect(syncs).to.deep.equal(expected); + expect(syncs).to.deep.equal(pixelSyncs); + }); + + it('should return pixel user syncs for pbs mode when iframe mode disabled', function () { + // Set spec.syncStore vars + const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub.withArgs('improvedigital.pbs').returns(true); + spec.buildRequests([simpleBidRequest], bidderRequest); + + const syncs = spec.getUserSyncs({ pixelEnabled: true }, serverResponses); + expect(syncs).to.deep.equal(pixelSyncs); + getConfigStub.restore(); + }); + + it('should return iframe user sync for the ad server mode when pixel mode disabled', function () { + spec.buildRequests([simpleBidRequest], bidderRequest); + const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses); + expect(syncs).to.deep.equal([{ type: 'iframe', url: basicIframeSyncUrl }]); + }); + + it('should attach consent to iframe sync url', function () { + spec.buildRequests([simpleBidRequest], bidderRequest); + let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses, gdprConsent); + expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&gdpr=1&gdpr_consent=CONSENT` }]); + + syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses, { gdprApplies: false }); + expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&gdpr=0` }]); + }); + + it('should return iframe user sync for the pbs mode when iframe mode enabled', function () { + const expectedSync = [{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]; + spec.buildRequests([simpleBidRequest, pbsBidRequest]); + let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); + expect(syncs).to.deep.equal(expectedSync); + + // Set spec.syncStore vars + const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub.withArgs('improvedigital.pbs').returns(true); + spec.buildRequests([simpleBidRequest], bidderRequest); + + syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); + expect(syncs).to.deep.equal(expectedSync); + getConfigStub.restore(); }); }); }); From bf293e23dc5c62389084ed3dd713f98ac8b4b363 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Tue, 3 May 2022 13:56:45 +0200 Subject: [PATCH 10/20] more unit tests --- .../modules/improvedigitalBidAdapter_spec.js | 56 ++++++++++++++----- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 92339153ae5..4561450ac72 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -515,12 +515,29 @@ describe('Improve Digital Adapter Tests', function () { it('should return one request in a single request mode', function () { const getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.singleRequest').returns(true); - const requests = spec.buildRequests([ - simpleBidRequest, - simpleSmartTagBidRequest - ], bidderRequest); + const requests = spec.buildRequests([ simpleBidRequest, instreamBidRequest ], bidderRequest); expect(requests).to.be.an('array'); expect(requests.length).to.equal(1); + expect(requests[0].url).to.equal(AD_SERVER_URL); + const request = JSON.parse(requests[0].data); + expect(request.imp.length).to.equal(2); + expect(request.imp[0].banner).to.exist; + expect(request.imp[1].video).to.exist; + getConfigStub.restore(); + }); + + it('should create one request per endpoint in a single request mode', function () { + const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub.withArgs('improvedigital.singleRequest').returns(true); + const requests = spec.buildRequests([ pbsBidRequest, simpleBidRequest, instreamBidRequest ], bidderRequest); + expect(requests).to.be.an('array'); + expect(requests.length).to.equal(2); + expect(requests[0].url).to.equal(PBS_URL); + expect(requests[1].url).to.equal(AD_SERVER_URL); + const adServerRequest = JSON.parse(requests[1].data); + expect(adServerRequest.imp.length).to.equal(2); + expect(adServerRequest.imp[0].banner).to.exist; + expect(adServerRequest.imp[1].video).to.exist; getConfigStub.restore(); }); @@ -676,20 +693,33 @@ describe('Improve Digital Adapter Tests', function () { getConfigStub.restore(); }); - it('should set pbs url when pbs mode enabled from global configuration', function () { + it('should set pbs params when pbs mode enabled from global configuration', function () { const getConfigStub = sinon.stub(config, 'getConfig'); + const bannerRequest = deepClone(simpleBidRequest); + const keyValues = { testKey: [ 'testValue' ] }; + bannerRequest.params.keyValues = keyValues; + getConfigStub.withArgs('improvedigital.pbs').returns(true); - const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; - expect(request.method).to.equal(METHOD); - expect(request.url).to.equal(PBS_URL); + const requests = spec.buildRequests([bannerRequest, instreamBidRequest], bidderRequest); + expect(requests[0].method).to.equal(METHOD); + expect(requests[0].url).to.equal(PBS_URL); + expect(requests[1].url).to.equal(PBS_URL); + // banner + let payload = JSON.parse(requests[0].data); + expect(payload.imp[0].ext.bidder).to.not.exist; + expect(payload.imp[0].ext.prebid.bidder.improvedigital).to.deep.equal({ + placementId: 1053688, + keyValues + }); + expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal('1053688'); + // video + payload = JSON.parse(requests[1].data); + expect(payload.imp[0].ext.bidder).to.not.exist; + expect(payload.imp[0].ext.prebid.bidder.improvedigital.placementId).to.equal(123456); + expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal('123456'); getConfigStub.restore(); }); - // expect(request.bidderRequest).to.deep.equal(bidderRequest); - // const payload = JSON.parse(request.data); - // expect(payload).to.be.an('object'); - // expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal(1053688); - it('should set pbs url when pbs mode enabled in adunit params', function () { const bidRequest = deepClone(pbsBidRequest); let request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; From 99972e1ac420a924d919febe398689f136b20761 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Tue, 3 May 2022 17:04:40 +0200 Subject: [PATCH 11/20] No user syncing for COPPA users --- modules/improvedigitalBidAdapter.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 1fb05335589..ed2a9585cca 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -218,8 +218,11 @@ export const spec = { * @return {UserSync[]} The user syncs which should be dropped. */ getUserSyncs(syncOptions, serverResponses, gdprConsent) { - const syncs = []; + if (config.getConfig('coppa') === true) { + return []; + } + const syncs = []; if ((this.syncStore.pbsMode || !syncOptions.pixelEnabled) && syncOptions.iframeEnabled) { const { gdprApplies, consentString } = gdprConsent || {}; syncs.push({ @@ -496,6 +499,7 @@ const ID_RESPONSE = { this.buildNativeAd(bid, bidRequest, bidResponse) } } else { + // Detect media type for multi-format response if (bidResponse.adm.search(/^(<\?xml| Date: Tue, 3 May 2022 17:22:50 +0200 Subject: [PATCH 12/20] more unit tests --- .../modules/improvedigitalBidAdapter_spec.js | 116 +++++++++++------- 1 file changed, 75 insertions(+), 41 deletions(-) diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 4561450ac72..7f00b4cfbfd 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { spec } from 'modules/improvedigitalBidAdapter.js'; import { config } from 'src/config.js'; import { deepClone } from 'src/utils.js'; -import {BANNER, VIDEO} from '../../../src/mediaTypes'; +import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes'; describe('Improve Digital Adapter Tests', function () { const METHOD = 'POST'; @@ -65,11 +65,19 @@ describe('Improve Digital Adapter Tests', function () { } }; + const nativeBidRequest = deepClone(simpleBidRequest); + nativeBidRequest.mediaTypes = { native: {} }; + const multiFormatBidRequest = deepClone(simpleBidRequest); multiFormatBidRequest.mediaTypes = { banner: { sizes: [[300, 250], [160, 600]] }, + native: { + body: { + required: true + } + }, video: { context: 'outstream', playerSize: [640, 480] @@ -106,6 +114,10 @@ describe('Improve Digital Adapter Tests', function () { bids: [multiFormatBidRequest] }; + const nativeBidderRequest = { + bids: [nativeBidRequest] + }; + const gdprConsent = { consentString: 'CONSENT', vendorData: {}, @@ -165,8 +177,17 @@ describe('Improve Digital Adapter Tests', function () { }); describe('buildRequests', function () { + let getConfigStub = null; + + afterEach(function () { + if (getConfigStub) { + getConfigStub.restore(); + getConfigStub = null; + } + }); + it('should make a well-formed request objects', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; expect(request).to.be.an('object'); @@ -201,11 +222,10 @@ describe('Improve Digital Adapter Tests', function () { } } ]); - getConfigStub.restore(); }); it('should make a well-formed request object for multi-format ad unit', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); const request = spec.buildRequests([multiFormatBidRequest], multiFormatBidderRequest)[0]; expect(request).to.be.an('object'); @@ -218,6 +238,10 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.imp).to.deep.equal([ { id: '33e9500b21129f', + native: { + request: '{"assets":[{"id":3,"required":1,"data":{"type":2}}]}', + ver: '1.2' + }, secure: 0, ext: { bidder: { @@ -238,7 +262,6 @@ describe('Improve Digital Adapter Tests', function () { } } ]); - getConfigStub.restore(); }); it('should set placementKey and publisherId for smart tags', function () { @@ -261,10 +284,9 @@ describe('Improve Digital Adapter Tests', function () { it('should add currency', function () { const bidRequest = Object.assign({}, simpleBidRequest); - const getConfigStub = sinon.stub(config, 'getConfig').returns('JPY'); + getConfigStub = sinon.stub(config, 'getConfig').returns('JPY'); const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest)[0].data); expect(payload.cur).to.deep.equal(['JPY']); - getConfigStub.restore(); }); it('should add bid floor', function () { @@ -513,7 +535,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should return one request in a single request mode', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.singleRequest').returns(true); const requests = spec.buildRequests([ simpleBidRequest, instreamBidRequest ], bidderRequest); expect(requests).to.be.an('array'); @@ -523,11 +545,10 @@ describe('Improve Digital Adapter Tests', function () { expect(request.imp.length).to.equal(2); expect(request.imp[0].banner).to.exist; expect(request.imp[1].video).to.exist; - getConfigStub.restore(); }); it('should create one request per endpoint in a single request mode', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.singleRequest').returns(true); const requests = spec.buildRequests([ pbsBidRequest, simpleBidRequest, instreamBidRequest ], bidderRequest); expect(requests).to.be.an('array'); @@ -538,11 +559,10 @@ describe('Improve Digital Adapter Tests', function () { expect(adServerRequest.imp.length).to.equal(2); expect(adServerRequest.imp[0].banner).to.exist; expect(adServerRequest.imp[1].video).to.exist; - getConfigStub.restore(); }); it('should set Prebid sizes in bid request', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; const payload = JSON.parse(request.data); @@ -552,11 +572,10 @@ describe('Improve Digital Adapter Tests', function () { { w: 160, h: 600 } ] }); - getConfigStub.restore(); }); it('should not add single size filter when using Prebid sizes', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); const bidRequest = Object.assign({}, simpleBidRequest); const size = { @@ -572,7 +591,6 @@ describe('Improve Digital Adapter Tests', function () { { w: 160, h: 600 } ] }); - getConfigStub.restore(); }); it('should set GPID and Instl Signal', function () { @@ -614,29 +632,27 @@ describe('Improve Digital Adapter Tests', function () { }); it('should not set site when app is defined in FPD', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('ortb2.app').returns({ content: 'XYZ' }); let request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; let payload = JSON.parse(request.data); expect(payload.site).does.not.exist; expect(payload.app).does.exist; expect(payload.app.content).does.exist.and.equal('XYZ'); - getConfigStub.restore(); }); it('should not set site when app is defined in CONFIG', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('app').returns({ content: 'XYZ' }); let request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; let payload = JSON.parse(request.data); expect(payload.site).does.not.exist; expect(payload.app).does.exist; expect(payload.app.content).does.exist.and.equal('XYZ'); - getConfigStub.restore(); }); it('should set correct site params', function () { - let getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('site').returns({ content: 'XYZ', page: 'https://improveditigal.com/', @@ -663,11 +679,10 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.site.content).does.exist.and.equal('ZZZ'); expect(payload.site.page).does.exist.and.equal('https://blah.com/test.html'); expect(payload.site.domain).does.exist.and.equal('blah.com'); - getConfigStub.restore(); }); it('should set pageUrl as site param', function () { - let getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('pageUrl').returns('https://improvidigital.com/test-page'); let request = spec.buildRequests([simpleBidRequest], bidderRequestReferrer)[0]; let payload = JSON.parse(request.data); @@ -680,21 +695,19 @@ describe('Improve Digital Adapter Tests', function () { payload = JSON.parse(request.data); expect(payload.site.page).does.exist.and.equal('https://blah.com/test.html'); expect(payload.site.domain).does.exist.and.equal('blah.com'); - getConfigStub.restore(); }); it('should set site when app not available', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('app').returns(undefined); let request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; let payload = JSON.parse(request.data); expect(payload.site).does.exist; expect(payload.app).does.not.exist; - getConfigStub.restore(); }); it('should set pbs params when pbs mode enabled from global configuration', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); const bannerRequest = deepClone(simpleBidRequest); const keyValues = { testKey: [ 'testValue' ] }; bannerRequest.params.keyValues = keyValues; @@ -717,7 +730,6 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.imp[0].ext.bidder).to.not.exist; expect(payload.imp[0].ext.prebid.bidder.improvedigital.placementId).to.equal(123456); expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal('123456'); - getConfigStub.restore(); }); it('should set pbs url when pbs mode enabled in adunit params', function () { @@ -725,7 +737,7 @@ describe('Improve Digital Adapter Tests', function () { let request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; expect(request.url).to.equal(PBS_URL); - const getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub = sinon.stub(config, 'getConfig'); // adunit param takes precedence over the global config getConfigStub.withArgs('improvedigital.pbs').returns(false); @@ -741,8 +753,6 @@ describe('Improve Digital Adapter Tests', function () { expect(requests.length).to.equal(2); expect(requests[0].url).to.equal(AD_SERVER_URL); expect(requests[1].url).to.equal(PBS_URL); - - getConfigStub.restore(); }); }); @@ -875,7 +885,7 @@ describe('Improve Digital Adapter Tests', function () { 'id': '52098fad-20c1-476b-a4fa-41e275e5a4a5', 'price': 1.8600000000000003, 'adm': "{\"ver\":\"1.1\",\"imptrackers\":[\"https://secure.adnxs.com/imptr?id=52311&t=2\",\"https://euw-ice.360yield.com/imp_pixel?ic=hcUBlCANx1FabHBf6FR2gC7UO4xEyXahdZAn0-B5qL-bb3A74BJ1smyWIyW7IWcC0SOjSXzVpevTHXxTqJ.sf.Qhahyy6tSo.0j1QWfXlH8sM4-8vKWjMjw-x.IrJJNlwkQ0s1CdwcwTefcLXm5l2E-W19VhACuV7f3mgrZMNjiSw.SjJAfyPC3SIyAMRjYfj53UmjriQ46T7lhmkqxK8wHmksYCdbZc3PZESk8NWl28sxdjNvnYYCFMcJbeav.LOLabyTXfwy-1cEPbQs.IKMRZIKaqccTDPV3wOtzbNv0jQzatd3Nnv-PGFQcjQ-GW3i27W04Fws4kodpFSn-B6VwZAjzLzoyd5gBncyRnAyCplEbgHU5sZ1IyKHWjgCl3ZtRIK5vqrRD5D-xqgSnOi7-phG.CqZWDZ4bMDSfQg2ZnbvUTyGKcEl0WR59dW5izTMV4Fjizcrvr5T-t.zMbGwz.hGnmLIyhTqh.IcwW.GiDLVExlDlix5S1LXIWVsSyrQ==\"],\"assets\":[{\"id\":1,\"data\":{\"value\":\"ImproveDigital\",\"type\":1}},{\"id\":3,\"data\":{\"value\":\"Test content.\",\"type\":2}},{\"id\":0,\"title\":{\"text\":\"Sample Prebid Test Title\"}}],\"link\":{\"url\":\"https://euw-ice.360yield.com/click/hcUBlHOV7YhVse8RyBa0ajjyPa9Vt17e4g-1m3cRj3E67vq-RYux.SiUeAmBfNBcoOqkUc6A15AWmi4yFu5K-BdkaYjildyyk7fNLyR6hWr411kv4vrFwm5jrIBceuHS6K8oN69f.uCo8zGTdR2TbSlldwcpahQPlufZU.6VaMsu4IC53uEiUT5vb7kAw6TTlxuGBNq6zaGryiWEV2.N3YYJDTyYPh8tv-ZFyeFZFm0Gnjv.xWbC.70JcRUVU9UelQaPsTpTWYTXBhJt84YJUw1-GNtaLNVLSjjZbVoA2fsMti5p6OBmF.7u39on2OPgvseIkSmge7Pqg63pRqdP75hp.DAEk6OkcN1jGnwP2DSbvpaSbin5lVqjfO0B-wnQgfQTCUtM5v4JmkNweLhUf9Q-x.nPKLW5SccEk9ZFXzY2-1wpT3PWm8Tix3NRscLPZub9wHzL..pl6ip8cQ9hp16UjwT4H6RMAxL0R7bl-h2pAicGAzYmuO7ntRESKUoIWA==//http%3A%2F%2Fquantum-advertising.com%2Ffr%2F\"},\"jstracker\":\"\"}", - 'impid': '2d7a7db325c6f', + 'impid': '33e9500b21129f', 'cid': '196108' } ], @@ -1128,10 +1138,6 @@ describe('Improve Digital Adapter Tests', function () { // // Native ads it('should return a well-formed native ad bid', function () { - const nativeBidderRequest = deepClone(bidderRequest); - nativeBidderRequest.bids[0].bidId = '2d7a7db325c6f'; - delete nativeBidderRequest.bids[0].mediaTypes.banner; - nativeBidderRequest.bids[0].mediaTypes.native = {}; const bids = spec.interpretResponse(serverResponseNative, {bidderRequest: nativeBidderRequest}); // Verify Native Response expect(bids[0].native).to.exist; @@ -1148,6 +1154,11 @@ describe('Improve Digital Adapter Tests', function () { expect(nativeBid.body).to.exist.and.equal('Test content.'); }); + it('should return a well-formed native bid for multi-format ad unit', function () { + const bids = spec.interpretResponse(serverResponseNative, {bidderRequest: multiFormatBidderRequest}); + expect(bids[0].mediaType).to.equal(NATIVE); + }); + // Video it('should return a well-formed instream video bid', function () { const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: instreamBidderRequest}); @@ -1162,10 +1173,19 @@ describe('Improve Digital Adapter Tests', function () { }); it('should return a well-formed outstream video bid for multi-format ad unit', function () { - const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: multiFormatBidderRequest}); + const videoResponse = deepClone(serverResponseVideo); + let bids = spec.interpretResponse(videoResponse, {bidderRequest: multiFormatBidderRequest}); expect(bids[0].renderer).to.exist; delete (bids[0].renderer); expect(bids).to.deep.equal(expectedBidOutstreamVideo); + + videoResponse.body.seatbid[0].bid[0].adm = ' Date: Wed, 4 May 2022 15:33:39 +0200 Subject: [PATCH 13/20] Adding USP consent and purpose 1 checks for syncs --- modules/improvedigitalBidAdapter.js | 17 ++++++++++++--- .../modules/improvedigitalBidAdapter_spec.js | 21 +++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index ed2a9585cca..a1ee7fd424e 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -217,8 +217,8 @@ export const spec = { * @param {ServerResponse[]} serverResponses List of server's responses. * @return {UserSync[]} The user syncs which should be dropped. */ - getUserSyncs(syncOptions, serverResponses, gdprConsent) { - if (config.getConfig('coppa') === true) { + getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) { + if (config.getConfig('coppa') === true || !ID_UTIL.hasPurpose1Consent({gdprConsent})) { return []; } @@ -231,7 +231,8 @@ export const spec = { `?placement_id=${this.syncStore.placementId}` + (this.syncStore.pbsMode ? '&pbs=1' : '') + (typeof gdprApplies !== 'undefined' ? `&gdpr=${ID_UTIL.toBit(gdprApplies)}` : '') + - (consentString ? `&gdpr_consent=${consentString}` : '') + (consentString ? `&gdpr_consent=${consentString}` : '') + + (uspConsent ? `&us_privacy=${encodeURIComponent(uspConsent)}` : '') }); } else if (syncOptions.pixelEnabled) { serverResponses.forEach(response => { @@ -646,6 +647,16 @@ const ID_RAZR = { }; const ID_UTIL = { + hasPurpose1Consent(bidderRequest) { + let result = true; + if (bidderRequest && bidderRequest.gdprConsent) { + if (bidderRequest.gdprConsent.gdprApplies && bidderRequest.gdprConsent.apiVersion === 2) { + result = !!(deepAccess(bidderRequest.gdprConsent, 'vendorData.purpose.consents.1') === true); + } + } + return result; + }, + toBit(val) { return val ? 1 : 0; }, diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 7f00b4cfbfd..0f8f82f4338 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -3,6 +3,7 @@ import { spec } from 'modules/improvedigitalBidAdapter.js'; import { config } from 'src/config.js'; import { deepClone } from 'src/utils.js'; import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes'; +import { deepSetValue } from '../../../src/utils'; describe('Improve Digital Adapter Tests', function () { const METHOD = 'POST'; @@ -119,8 +120,9 @@ describe('Improve Digital Adapter Tests', function () { }; const gdprConsent = { + apiVersion: 2, consentString: 'CONSENT', - vendorData: {}, + vendorData: { purpose: { consents: { 1: true } } }, gdprApplies: true, addtlConsent: '1~1.35.41.101', }; @@ -1210,6 +1212,8 @@ describe('Improve Digital Adapter Tests', function () { const basicIframeSyncUrl = `${IFRAME_SYNC_URL}?placement_id=1053688`; + const uspConsent = '1YYY'; + let getConfigStub = null; beforeEach(function () { @@ -1235,6 +1239,13 @@ describe('Improve Digital Adapter Tests', function () { expect(syncs).to.deep.equal([]); }); + it('should return no syncs for when GDPR consent for purpose 1 not given', function () { + const consent = deepClone(gdprConsent); + deepSetValue(consent, 'vendorData.purpose.consents.1', false); + const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses, consent); + expect(syncs).to.deep.equal([]); + }); + it('should return pixel user syncs for the ad server mode', function () { const syncs = spec.getUserSyncs({ pixelEnabled: true }, serverResponses); expect(syncs).to.deep.equal(pixelSyncs); @@ -1256,7 +1267,7 @@ describe('Improve Digital Adapter Tests', function () { expect(syncs).to.deep.equal([{ type: 'iframe', url: basicIframeSyncUrl }]); }); - it('should attach consent to iframe sync url', function () { + it('should attach gdpr consent to iframe sync url', function () { spec.buildRequests([simpleBidRequest], bidderRequest); let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses, gdprConsent); expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&gdpr=1&gdpr_consent=CONSENT` }]); @@ -1265,6 +1276,12 @@ describe('Improve Digital Adapter Tests', function () { expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&gdpr=0` }]); }); + it('should attach usp consent to iframe sync url', function () { + spec.buildRequests([simpleBidRequest], bidderRequest); + let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponses, null, uspConsent); + expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&us_privacy=${uspConsent}` }]); + }); + it('should return iframe user sync for the pbs mode when iframe mode enabled', function () { const expectedSync = [{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]; spec.buildRequests([simpleBidRequest, pbsBidRequest]); From 4f61b3a5b430e99f3b399cb7b52b51c50b8fe524 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Wed, 4 May 2022 16:55:54 +0200 Subject: [PATCH 14/20] Native ads: change asset param --- modules/improvedigitalBidAdapter.js | 14 +++- .../modules/improvedigitalBidAdapter_spec.js | 71 +++++++++++++------ 2 files changed, 63 insertions(+), 22 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index d1c35f63f9a..9de2e2b2d32 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -304,7 +304,10 @@ const ID_REQUEST = { } if (deepAccess(bidRequest, 'mediaTypes.native')) { - imp.native = this.buildNativeRequest(bidRequest); + const nativeImp = this.buildNativeRequest(bidRequest); + if (nativeImp) { + imp.native = nativeImp; + } } return imp; @@ -358,7 +361,10 @@ const ID_REQUEST = { }, buildNativeRequest(bidRequest) { - const nativeParams = bidRequest.mediaTypes.native; + const nativeParams = bidRequest.nativeParams; + if (!nativeParams) { + return null; + } const request = { assets: [], } @@ -392,6 +398,10 @@ const ID_REQUEST = { request.assets.push(asset); } } + if (!request.assets.length) { + logWarn('No native assets recognized. Ignoring native ad request'); + return null; + } return { ver: NATIVE_DATA.VERSION, request: JSON.stringify(request) }; }, diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index d721c2d20bc..8004c8d6f62 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { spec } from 'modules/improvedigitalBidAdapter.js'; import { config } from 'src/config.js'; import { deepClone } from 'src/utils.js'; -import {BANNER, VIDEO} from '../../../src/mediaTypes'; +import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes'; describe('Improve Digital Adapter Tests', function () { const METHOD = 'POST'; @@ -50,17 +50,31 @@ describe('Improve Digital Adapter Tests', function () { } }; + const nativeBidRequest = deepClone(simpleBidRequest); + nativeBidRequest.mediaTypes = { native: {} }; + nativeBidRequest.nativeParams = { + title: {required: true}, + body: {required: true} + }; + const multiFormatBidRequest = deepClone(simpleBidRequest); multiFormatBidRequest.mediaTypes = { banner: { sizes: [[300, 250], [160, 600]] }, + native: {}, video: { context: 'outstream', playerSize: [640, 480] } }; + multiFormatBidRequest.nativeParams = { + body: { + required: true + } + }; + const simpleSmartTagBidRequest = { bidder: 'improvedigital', bidId: '1a2b3c', @@ -87,6 +101,10 @@ describe('Improve Digital Adapter Tests', function () { bids: [multiFormatBidRequest] }; + const nativeBidderRequest = { + bids: [nativeBidRequest] + }; + const bidderRequestGdpr = { bids: [simpleBidRequest], gdprConsent: { @@ -197,6 +215,10 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.imp).to.deep.equal([ { id: '33e9500b21129f', + native: { + request: '{"assets":[{"id":3,"required":1,"data":{"type":2}}]}', + ver: '1.2' + }, secure: 0, ext: { bidder: { @@ -220,6 +242,28 @@ describe('Improve Digital Adapter Tests', function () { getConfigStub.restore(); }); + it('should make a well-formed native request', function () { + const payload = JSON.parse(spec.buildRequests([nativeBidRequest])[0].data); + expect(payload.imp[0].native).to.deep.equal({ + ver: '1.2', + request: '{\"assets\":[{\"id\":0,\"required\":1,\"title\":{\"len\":140}},{\"id\":3,\"required\":1,\"data\":{\"type\":2}}]}' + }); + }); + + it('should not make native request when nativeParams is undefined', function () { + const request = deepClone(nativeBidRequest); + delete request.nativeParams; + const payload = JSON.parse(spec.buildRequests([request])[0].data); + expect(payload.imp[0].native).to.not.exist; + }); + + it('should not make native request when no assets', function () { + const request = deepClone(nativeBidRequest); + request.nativeParams = {}; + const payload = JSON.parse(spec.buildRequests([request])[0].data); + expect(payload.imp[0].native).to.not.exist; + }); + it('should set placementKey and publisherId for smart tags', function () { const payload = JSON.parse(spec.buildRequests([simpleSmartTagBidRequest], bidderRequest)[0].data); expect(payload.imp[0].ext.bidder.publisherId).to.equal(1032); @@ -238,20 +282,6 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.imp[0].ext.bidder.keyValues).to.deep.equal(keyValues); }); - // it('should add single size filter', function () { - // const bidRequest = Object.assign({}, simpleBidRequest); - // const size = { - // w: 800, - // h: 600 - // }; - // bidRequest.params.size = size; - // const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest).data); - // expect(payload.imp[0].banner).to.deep.equal(size); - // // When single size filter is set, format shouldn't be populated. This - // // is to maintain backward compatibily - // expect(payload.imp[0].banner.format).to.not.exist; - // }); - it('should add currency', function () { const bidRequest = Object.assign({}, simpleBidRequest); const getConfigStub = sinon.stub(config, 'getConfig').returns('JPY'); @@ -790,7 +820,7 @@ describe('Improve Digital Adapter Tests', function () { 'id': '52098fad-20c1-476b-a4fa-41e275e5a4a5', 'price': 1.8600000000000003, 'adm': "{\"ver\":\"1.1\",\"imptrackers\":[\"https://secure.adnxs.com/imptr?id=52311&t=2\",\"https://euw-ice.360yield.com/imp_pixel?ic=hcUBlCANx1FabHBf6FR2gC7UO4xEyXahdZAn0-B5qL-bb3A74BJ1smyWIyW7IWcC0SOjSXzVpevTHXxTqJ.sf.Qhahyy6tSo.0j1QWfXlH8sM4-8vKWjMjw-x.IrJJNlwkQ0s1CdwcwTefcLXm5l2E-W19VhACuV7f3mgrZMNjiSw.SjJAfyPC3SIyAMRjYfj53UmjriQ46T7lhmkqxK8wHmksYCdbZc3PZESk8NWl28sxdjNvnYYCFMcJbeav.LOLabyTXfwy-1cEPbQs.IKMRZIKaqccTDPV3wOtzbNv0jQzatd3Nnv-PGFQcjQ-GW3i27W04Fws4kodpFSn-B6VwZAjzLzoyd5gBncyRnAyCplEbgHU5sZ1IyKHWjgCl3ZtRIK5vqrRD5D-xqgSnOi7-phG.CqZWDZ4bMDSfQg2ZnbvUTyGKcEl0WR59dW5izTMV4Fjizcrvr5T-t.zMbGwz.hGnmLIyhTqh.IcwW.GiDLVExlDlix5S1LXIWVsSyrQ==\"],\"assets\":[{\"id\":1,\"data\":{\"value\":\"ImproveDigital\",\"type\":1}},{\"id\":3,\"data\":{\"value\":\"Test content.\",\"type\":2}},{\"id\":0,\"title\":{\"text\":\"Sample Prebid Test Title\"}}],\"link\":{\"url\":\"https://euw-ice.360yield.com/click/hcUBlHOV7YhVse8RyBa0ajjyPa9Vt17e4g-1m3cRj3E67vq-RYux.SiUeAmBfNBcoOqkUc6A15AWmi4yFu5K-BdkaYjildyyk7fNLyR6hWr411kv4vrFwm5jrIBceuHS6K8oN69f.uCo8zGTdR2TbSlldwcpahQPlufZU.6VaMsu4IC53uEiUT5vb7kAw6TTlxuGBNq6zaGryiWEV2.N3YYJDTyYPh8tv-ZFyeFZFm0Gnjv.xWbC.70JcRUVU9UelQaPsTpTWYTXBhJt84YJUw1-GNtaLNVLSjjZbVoA2fsMti5p6OBmF.7u39on2OPgvseIkSmge7Pqg63pRqdP75hp.DAEk6OkcN1jGnwP2DSbvpaSbin5lVqjfO0B-wnQgfQTCUtM5v4JmkNweLhUf9Q-x.nPKLW5SccEk9ZFXzY2-1wpT3PWm8Tix3NRscLPZub9wHzL..pl6ip8cQ9hp16UjwT4H6RMAxL0R7bl-h2pAicGAzYmuO7ntRESKUoIWA==//http%3A%2F%2Fquantum-advertising.com%2Ffr%2F\"},\"jstracker\":\"\"}", - 'impid': '2d7a7db325c6f', + 'impid': '33e9500b21129f', 'cid': '196108' } ], @@ -1043,10 +1073,6 @@ describe('Improve Digital Adapter Tests', function () { // // Native ads it('should return a well-formed native ad bid', function () { - const nativeBidderRequest = JSON.parse(JSON.stringify(bidderRequest)); - nativeBidderRequest.bids[0].bidId = '2d7a7db325c6f'; - delete nativeBidderRequest.bids[0].mediaTypes.banner; - nativeBidderRequest.bids[0].mediaTypes.native = {}; const bids = spec.interpretResponse(serverResponseNative, {bidderRequest: nativeBidderRequest}); // Verify Native Response expect(bids[0].native).to.exist; @@ -1063,6 +1089,11 @@ describe('Improve Digital Adapter Tests', function () { expect(nativeBid.body).to.exist.and.equal('Test content.'); }); + it('should return a well-formed native bid for multi-format ad unit', function () { + const bids = spec.interpretResponse(serverResponseNative, {bidderRequest: multiFormatBidderRequest}); + expect(bids[0].mediaType).to.equal(NATIVE); + }); + // Video it('should return a well-formed instream video bid', function () { const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: instreamBidderRequest}); From 4779fae337e2793aaafcd90e8d11436fa0c187b7 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Thu, 5 May 2022 09:54:48 +0200 Subject: [PATCH 15/20] improvements --- modules/improvedigitalBidAdapter.js | 16 ++++++---------- .../modules/improvedigitalBidAdapter_spec.js | 12 ++++++++++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 0cdd9b13709..1a02cf4e78d 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -104,7 +104,7 @@ export const spec = { // Coppa const coppa = config.getConfig('coppa'); if (typeof coppa === 'boolean') { - deepSetValue(request, 'regs.coppa', ID_UTIL.toBit(coppa)); + deepSetValue(request, 'regs.coppa', Number(coppa)); } if (bidderRequest) { @@ -112,7 +112,7 @@ export const spec = { const gdprConsent = deepAccess(bidderRequest, 'gdprConsent') if (gdprConsent) { if (typeof gdprConsent.gdprApplies === 'boolean') { - deepSetValue(request, 'regs.ext.gdpr', ID_UTIL.toBit(gdprConsent.gdprApplies)); + deepSetValue(request, 'regs.ext.gdpr', Number(gdprConsent.gdprApplies)); } deepSetValue(request, 'user.ext.consent', gdprConsent.consentString); @@ -230,7 +230,7 @@ export const spec = { url: IFRAME_SYNC_URL + `?placement_id=${this.syncStore.placementId}` + (this.syncStore.pbsMode ? '&pbs=1' : '') + - (typeof gdprApplies !== 'undefined' ? `&gdpr=${ID_UTIL.toBit(gdprApplies)}` : '') + + (typeof gdprApplies === 'boolean' ? `&gdpr=${Number(gdprApplies)}` : '') + (consentString ? `&gdpr_consent=${consentString}` : '') + (uspConsent ? `&us_privacy=${encodeURIComponent(uspConsent)}` : '') }); @@ -308,7 +308,7 @@ const ID_REQUEST = { buildImp(bidRequest, pbsMode) { const imp = { id: getBidIdParameter('bidId', bidRequest) || getUniqueIdentifierStr(), - secure: ID_UTIL.toBit(window.location.protocol === 'https:'), + secure: Number(window.location.protocol === 'https:'), }; // Floor @@ -426,7 +426,7 @@ const ID_REQUEST = { const assetParams = nativeParams[i]; const asset = { id: assetOrtbParams.id, - required: ID_UTIL.toBit(assetParams.required), + required: Number(assetParams.required), }; switch (assetOrtbParams.assetType) { case NATIVE_DATA.ASSET_TYPES.TITLE: @@ -665,9 +665,5 @@ const ID_UTIL = { } } return result; - }, - - toBit(val) { - return val ? 1 : 0; - }, + } }; diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 876f7e60882..39975970c07 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -368,6 +368,18 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.regs.ext.us_privacy).to.equal('1YYY'); }); + it('should add COPPA flag', function () { + getConfigStub = sinon.stub(config, 'getConfig'); + getConfigStub.withArgs('coppa').returns(true); + let bidRequest = Object.assign({}, simpleBidRequest); + let payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequestGdpr)[0].data); + expect(payload.regs.coppa).to.equal(1); + getConfigStub.withArgs('coppa').returns(false); + bidRequest = Object.assign({}, simpleBidRequest); + payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequestGdpr)[0].data); + expect(payload.regs.coppa).to.equal(0); + }); + it('should add referrer', function () { const bidRequest = Object.assign({}, simpleBidRequest); const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0]; From a43e0426fffe00a80017e6c64c2731fa43db5e79 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Thu, 5 May 2022 12:39:59 +0200 Subject: [PATCH 16/20] refactoring --- modules/improvedigitalBidAdapter.js | 75 ++++++++++--------- .../modules/improvedigitalBidAdapter_spec.js | 2 +- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 1a02cf4e78d..cb52bc3ac3b 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -81,7 +81,6 @@ export const spec = { */ buildRequests(bidRequests, bidderRequest) { const request = { - id: getUniqueIdentifierStr(), cur: [config.getConfig('currency.adServerCurrency') || 'USD'], ext: { improvedigital: { @@ -252,49 +251,51 @@ export const spec = { registerBidder(spec); const ID_REQUEST = { - buildServerRequests(requestObject, bidRequests, bidderRequest) { + buildServerRequests(basicRequest, bidRequests, bidderRequest) { const globalPbsMode = config.getConfig('improvedigital.pbs') === true; const requests = []; - if (config.getConfig('improvedigital.singleRequest') === true) { - // Split imps between those going to the ad server and those going to PBS - const pbsImps = []; - const nonPbsImps = []; - bidRequests.map((bidRequest) => { - const pbsModeEnabled = this.isPbsModeEnabled(globalPbsMode, bidRequest.params); - const imp = this.buildImp(bidRequest, pbsModeEnabled) - pbsModeEnabled ? pbsImps.push(imp) : nonPbsImps.push(imp); - }); - if (pbsImps.length) { - const request = deepClone(requestObject); - request.imp = pbsImps; - requests.push(this.formatRequest(request, bidderRequest, true)); + const singleRequestMode = config.getConfig('improvedigital.singleRequest') === true; + + const pbsImps = []; + const adServerImps = []; + + function formatRequest(imps, transactionId, pbsMode) { + const request = deepClone(basicRequest); + request.imp = imps; + request.id = getUniqueIdentifierStr(); + if (transactionId) { + deepSetValue(request, 'source.tid', transactionId); } - if (nonPbsImps.length) { - const request = deepClone(requestObject); - request.imp = nonPbsImps; - requests.push(this.formatRequest(request, bidderRequest, false)); + return { + method: 'POST', + url: pbsMode ? PBS_URL : AD_SERVER_URL, + data: JSON.stringify(request), + bidderRequest } - } else { - bidRequests.map((bidRequest) => { - const request = deepClone(requestObject); - const pbsModeEnabled = this.isPbsModeEnabled(globalPbsMode, bidRequest.params); - request.id = bidRequest.bidId || getUniqueIdentifierStr(); - request.imp = [this.buildImp(bidRequest, pbsModeEnabled)]; - deepSetValue(request, 'source.tid', bidRequest.transactionId); - requests.push(this.formatRequest(request, bidderRequest, pbsModeEnabled)); - }); - } + }; - return requests; - }, + bidRequests.map((bidRequest) => { + const pbsModeEnabled = this.isPbsModeEnabled(globalPbsMode, bidRequest.params); + const imp = this.buildImp(bidRequest, pbsModeEnabled); + if (singleRequestMode) { + pbsModeEnabled ? pbsImps.push(imp) : adServerImps.push(imp); + } else { + requests.push(formatRequest([imp], bidRequest.transactionId, pbsModeEnabled)); + } + }); - formatRequest(request, bidderRequest, pbsMode) { - return { - method: 'POST', - url: pbsMode ? PBS_URL : AD_SERVER_URL, - data: JSON.stringify(request), - bidderRequest + if (!singleRequestMode) { + return requests; } + // In the single request mode, split imps between those going to the ad server and those going to PBS + if (pbsImps.length) { + requests.push(formatRequest(pbsImps, null, true)); + } + if (adServerImps.length) { + requests.push(formatRequest(adServerImps, null, false)); + } + + return requests; }, isPbsModeEnabled(globalPbsMode, bidParams) { diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 39975970c07..35a28147dd4 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -210,7 +210,7 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.cur).to.be.an('array'); expect(payload.regs).to.not.exist; expect(payload.schain).to.not.exist; - expect(payload.source).to.be.an('object'); + expect(payload.source).to.deep.equal({ ext: {}, tid: 'f183e871-fbed-45f0-a427-c8a63c4c01eb' }); expect(payload.device).to.be.an('object'); expect(payload.user).to.not.exist; expect(payload.imp).to.deep.equal([ From 73ed9566d928fdca9a34d0a7ccaab6d5fca76c7b Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Thu, 5 May 2022 13:01:06 +0200 Subject: [PATCH 17/20] refactoring --- modules/improvedigitalBidAdapter.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index cb52bc3ac3b..ee4b9e82afb 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -217,7 +217,7 @@ export const spec = { * @return {UserSync[]} The user syncs which should be dropped. */ getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) { - if (config.getConfig('coppa') === true || !ID_UTIL.hasPurpose1Consent({gdprConsent})) { + if (config.getConfig('coppa') === true || !ID_UTIL.hasPurpose1Consent(gdprConsent)) { return []; } @@ -658,13 +658,10 @@ const ID_RAZR = { }; const ID_UTIL = { - hasPurpose1Consent(bidderRequest) { - let result = true; - if (bidderRequest && bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.gdprApplies && bidderRequest.gdprConsent.apiVersion === 2) { - result = !!(deepAccess(bidderRequest.gdprConsent, 'vendorData.purpose.consents.1') === true); - } + hasPurpose1Consent(gdprConsent) { + if (gdprConsent && gdprConsent.gdprApplies && gdprConsent.apiVersion === 2) { + return (deepAccess(gdprConsent, 'vendorData.purpose.consents.1') === true); } - return result; + return true; } }; From 18e3eec694937b44a12a8ecc82816fef56c08a49 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Mon, 9 May 2022 10:00:15 +0200 Subject: [PATCH 18/20] Rename PBS mode to Extend --- modules/improvedigitalBidAdapter.js | 47 ++++++++--------- .../modules/improvedigitalBidAdapter_spec.js | 50 +++++++++---------- 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index ee4b9e82afb..e50818f7a4d 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -12,7 +12,7 @@ const BIDDER_CODE = 'improvedigital'; const CREATIVE_TTL = 300; const AD_SERVER_URL = 'https://ad.360yield.com/pb'; -const PBS_URL = 'https://pbs.360yield.com/openrtb2/auction'; +const EXTEND_URL = 'https://pbs.360yield.com/openrtb2/auction'; const IFRAME_SYNC_URL = 'https://hb.360yield.com/prebid-universal-creative/load-cookie.html'; const VIDEO_PARAMS = { @@ -60,7 +60,7 @@ export const spec = { gvlid: 253, aliases: ['id'], supportedMediaTypes: [BANNER, NATIVE, VIDEO], - syncStore: { pbsMode: false, placementId: null }, + syncStore: { extendMode: false, placementId: null }, /** * Determines whether or not the given bid request is valid. @@ -82,6 +82,7 @@ export const spec = { buildRequests(bidRequests, bidderRequest) { const request = { cur: [config.getConfig('currency.adServerCurrency') || 'USD'], + test: 1, ext: { improvedigital: { sdk: { @@ -222,13 +223,13 @@ export const spec = { } const syncs = []; - if ((this.syncStore.pbsMode || !syncOptions.pixelEnabled) && syncOptions.iframeEnabled) { + if ((this.syncStore.extendMode || !syncOptions.pixelEnabled) && syncOptions.iframeEnabled) { const { gdprApplies, consentString } = gdprConsent || {}; syncs.push({ type: 'iframe', url: IFRAME_SYNC_URL + `?placement_id=${this.syncStore.placementId}` + - (this.syncStore.pbsMode ? '&pbs=1' : '') + + (this.syncStore.extendMode ? '&pbs=1' : '') + (typeof gdprApplies === 'boolean' ? `&gdpr=${Number(gdprApplies)}` : '') + (consentString ? `&gdpr_consent=${consentString}` : '') + (uspConsent ? `&us_privacy=${encodeURIComponent(uspConsent)}` : '') @@ -252,14 +253,14 @@ registerBidder(spec); const ID_REQUEST = { buildServerRequests(basicRequest, bidRequests, bidderRequest) { - const globalPbsMode = config.getConfig('improvedigital.pbs') === true; + const globalExtendMode = config.getConfig('improvedigital.extend') === true; const requests = []; const singleRequestMode = config.getConfig('improvedigital.singleRequest') === true; - const pbsImps = []; + const extendImps = []; const adServerImps = []; - function formatRequest(imps, transactionId, pbsMode) { + function formatRequest(imps, transactionId, extendMode) { const request = deepClone(basicRequest); request.imp = imps; request.id = getUniqueIdentifierStr(); @@ -268,28 +269,28 @@ const ID_REQUEST = { } return { method: 'POST', - url: pbsMode ? PBS_URL : AD_SERVER_URL, + url: extendMode ? EXTEND_URL : AD_SERVER_URL, data: JSON.stringify(request), bidderRequest } }; bidRequests.map((bidRequest) => { - const pbsModeEnabled = this.isPbsModeEnabled(globalPbsMode, bidRequest.params); - const imp = this.buildImp(bidRequest, pbsModeEnabled); + const extendModeEnabled = this.isExtendModeEnabled(globalExtendMode, bidRequest.params); + const imp = this.buildImp(bidRequest, extendModeEnabled); if (singleRequestMode) { - pbsModeEnabled ? pbsImps.push(imp) : adServerImps.push(imp); + extendModeEnabled ? extendImps.push(imp) : adServerImps.push(imp); } else { - requests.push(formatRequest([imp], bidRequest.transactionId, pbsModeEnabled)); + requests.push(formatRequest([imp], bidRequest.transactionId, extendModeEnabled)); } }); if (!singleRequestMode) { return requests; } - // In the single request mode, split imps between those going to the ad server and those going to PBS - if (pbsImps.length) { - requests.push(formatRequest(pbsImps, null, true)); + // In the single request mode, split imps between those going to the ad server and those going to extend server + if (extendImps.length) { + requests.push(formatRequest(extendImps, null, true)); } if (adServerImps.length) { requests.push(formatRequest(adServerImps, null, false)); @@ -298,15 +299,15 @@ const ID_REQUEST = { return requests; }, - isPbsModeEnabled(globalPbsMode, bidParams) { - const pbsMode = typeof bidParams.pbs === 'boolean' ? bidParams.pbs : globalPbsMode; - if (pbsMode && !spec.syncStore.pbsMode) { - spec.syncStore.pbsMode = true; + isExtendModeEnabled(globalExtendMode, bidParams) { + const extendMode = typeof bidParams.extend === 'boolean' ? bidParams.extend : globalExtendMode; + if (extendMode && !spec.syncStore.extendMode) { + spec.syncStore.extendMode = true; } - return pbsMode; + return extendMode; }, - buildImp(bidRequest, pbsMode) { + buildImp(bidRequest, extendMode) { const imp = { id: getBidIdParameter('bidId', bidRequest) || getUniqueIdentifierStr(), secure: Number(window.location.protocol === 'https:'), @@ -320,11 +321,11 @@ const ID_REQUEST = { deepSetValue(imp, 'bidfloorcur', bidFloorCur ? bidFloorCur.toUpperCase() : undefined); } - const bidderParamsPath = pbsMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; + const bidderParamsPath = extendMode ? 'ext.prebid.bidder.improvedigital' : 'ext.bidder'; const placementId = getBidIdParameter('placementId', bidRequest.params); if (placementId) { deepSetValue(imp, `${bidderParamsPath}.placementId`, placementId); - if (pbsMode) { + if (extendMode) { deepSetValue(imp, 'ext.prebid.storedrequest.id', '' + placementId); } } else { diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 35a28147dd4..b0d471a2520 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -8,7 +8,7 @@ import { deepSetValue } from '../../../src/utils'; describe('Improve Digital Adapter Tests', function () { const METHOD = 'POST'; const AD_SERVER_URL = 'https://ad.360yield.com/pb'; - const PBS_URL = 'https://pbs.360yield.com/openrtb2/auction'; + const EXTEND_URL = 'https://pbs.360yield.com/openrtb2/auction'; const IFRAME_SYNC_URL = 'https://hb.360yield.com/prebid-universal-creative/load-cookie.html'; const INSTREAM_TYPE = 1; const OUTSTREAM_TYPE = 3; @@ -31,8 +31,8 @@ describe('Improve Digital Adapter Tests', function () { sizes: [[300, 250], [160, 600]] }; - const pbsBidRequest = deepClone(simpleBidRequest); - pbsBidRequest.params.pbs = true; + const extendBidRequest = deepClone(simpleBidRequest); + extendBidRequest.params.extend = true; const videoParams = { skip: 1, @@ -105,8 +105,8 @@ describe('Improve Digital Adapter Tests', function () { bids: [simpleBidRequest] }; - const pbsBidderRequest = { - bids: [pbsBidRequest] + const extendBidderRequest = { + bids: [extendBidRequest] }; const instreamBidderRequest = { @@ -592,10 +592,10 @@ describe('Improve Digital Adapter Tests', function () { it('should create one request per endpoint in a single request mode', function () { getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.singleRequest').returns(true); - const requests = spec.buildRequests([ pbsBidRequest, simpleBidRequest, instreamBidRequest ], bidderRequest); + const requests = spec.buildRequests([ extendBidRequest, simpleBidRequest, instreamBidRequest ], bidderRequest); expect(requests).to.be.an('array'); expect(requests.length).to.equal(2); - expect(requests[0].url).to.equal(PBS_URL); + expect(requests[0].url).to.equal(EXTEND_URL); expect(requests[1].url).to.equal(AD_SERVER_URL); const adServerRequest = JSON.parse(requests[1].data); expect(adServerRequest.imp.length).to.equal(2); @@ -748,17 +748,17 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.app).does.not.exist; }); - it('should set pbs params when pbs mode enabled from global configuration', function () { + it('should set extend params when extend mode enabled from global configuration', function () { getConfigStub = sinon.stub(config, 'getConfig'); const bannerRequest = deepClone(simpleBidRequest); const keyValues = { testKey: [ 'testValue' ] }; bannerRequest.params.keyValues = keyValues; - getConfigStub.withArgs('improvedigital.pbs').returns(true); + getConfigStub.withArgs('improvedigital.extend').returns(true); const requests = spec.buildRequests([bannerRequest, instreamBidRequest], bidderRequest); expect(requests[0].method).to.equal(METHOD); - expect(requests[0].url).to.equal(PBS_URL); - expect(requests[1].url).to.equal(PBS_URL); + expect(requests[0].url).to.equal(EXTEND_URL); + expect(requests[1].url).to.equal(EXTEND_URL); // banner let payload = JSON.parse(requests[0].data); expect(payload.imp[0].ext.bidder).to.not.exist; @@ -774,27 +774,27 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.imp[0].ext.prebid.storedrequest.id).to.equal('123456'); }); - it('should set pbs url when pbs mode enabled in adunit params', function () { - const bidRequest = deepClone(pbsBidRequest); + it('should set extend url when extend mode enabled in adunit params', function () { + const bidRequest = deepClone(extendBidRequest); let request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; - expect(request.url).to.equal(PBS_URL); + expect(request.url).to.equal(EXTEND_URL); getConfigStub = sinon.stub(config, 'getConfig'); // adunit param takes precedence over the global config - getConfigStub.withArgs('improvedigital.pbs').returns(false); + getConfigStub.withArgs('improvedigital.extend').returns(false); request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; - expect(request.url).to.equal(PBS_URL); + expect(request.url).to.equal(EXTEND_URL); - bidRequest.params.pbs = false; - getConfigStub.withArgs('improvedigital.pbs').returns(true); + bidRequest.params.extend = false; + getConfigStub.withArgs('improvedigital.extend').returns(true); request = spec.buildRequests([bidRequest], { bids: [bidRequest] })[0]; expect(request.url).to.equal(AD_SERVER_URL); const requests = spec.buildRequests([bidRequest, instreamBidRequest], { bids: [bidRequest, instreamBidRequest] }); expect(requests.length).to.equal(2); expect(requests[0].url).to.equal(AD_SERVER_URL); - expect(requests[1].url).to.equal(PBS_URL); + expect(requests[1].url).to.equal(EXTEND_URL); }); }); @@ -1257,7 +1257,7 @@ describe('Improve Digital Adapter Tests', function () { let getConfigStub = null; beforeEach(function () { - spec.syncStore = { pbsMode: false, placementId: null }; + spec.syncStore = { extendMode: false, placementId: null }; }); afterEach(function () { @@ -1291,10 +1291,10 @@ describe('Improve Digital Adapter Tests', function () { expect(syncs).to.deep.equal(pixelSyncs); }); - it('should return pixel user syncs for pbs mode when iframe mode disabled', function () { + it('should return pixel user syncs for extend mode when iframe mode disabled', function () { // Set spec.syncStore vars getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.pbs').returns(true); + getConfigStub.withArgs('improvedigital.extend').returns(true); spec.buildRequests([simpleBidRequest], bidderRequest); const syncs = spec.getUserSyncs({ pixelEnabled: true }, serverResponses); @@ -1322,15 +1322,15 @@ describe('Improve Digital Adapter Tests', function () { expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&us_privacy=${uspConsent}` }]); }); - it('should return iframe user sync for the pbs mode when iframe mode enabled', function () { + it('should return iframe user sync for the extend mode when iframe mode enabled', function () { const expectedSync = [{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]; - spec.buildRequests([simpleBidRequest, pbsBidRequest]); + spec.buildRequests([simpleBidRequest, extendBidRequest]); let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); expect(syncs).to.deep.equal(expectedSync); // Set spec.syncStore vars getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.pbs').returns(true); + getConfigStub.withArgs('improvedigital.extend').returns(true); spec.buildRequests([simpleBidRequest], bidderRequest); syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); From 9cdac9a39f1c940b608ca72f3ea6b943c23785c8 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Mon, 9 May 2022 10:01:27 +0200 Subject: [PATCH 19/20] Remove test --- modules/improvedigitalBidAdapter.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index e50818f7a4d..a0453466b87 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -82,7 +82,6 @@ export const spec = { buildRequests(bidRequests, bidderRequest) { const request = { cur: [config.getConfig('currency.adServerCurrency') || 'USD'], - test: 1, ext: { improvedigital: { sdk: { From 605e61348bdfe8029d16441081bb5ba292c9e537 Mon Sep 17 00:00:00 2001 From: Jozef Bartek Date: Mon, 9 May 2022 10:46:40 +0200 Subject: [PATCH 20/20] minor test fix --- .../modules/improvedigitalBidAdapter_spec.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index b0d471a2520..5575e1e8e0b 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -1322,19 +1322,20 @@ describe('Improve Digital Adapter Tests', function () { expect(syncs).to.deep.equal([{ type: 'iframe', url: `${basicIframeSyncUrl}&us_privacy=${uspConsent}` }]); }); - it('should return iframe user sync for the extend mode when iframe mode enabled', function () { - const expectedSync = [{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]; + it('should return iframe user sync for the adunit extend mode if iframe mode enabled', function () { + // buildRequests() sets spec.syncStore vars spec.buildRequests([simpleBidRequest, extendBidRequest]); - let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); - expect(syncs).to.deep.equal(expectedSync); + const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); + expect(syncs).to.deep.equal([{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]); + }); - // Set spec.syncStore vars + it('should return iframe user sync for the global extend mode if iframe mode enabled', function () { getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.extend').returns(true); - spec.buildRequests([simpleBidRequest], bidderRequest); - - syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); - expect(syncs).to.deep.equal(expectedSync); + // buildRequests() sets spec.syncStore vars + spec.buildRequests([simpleBidRequest]); + const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses); + expect(syncs).to.deep.equal([{ type: 'iframe', url: basicIframeSyncUrl + '&pbs=1' }]); }); }); });