From 6bd8ba61235a7368edf284df5e9dfe866dc9a9d4 Mon Sep 17 00:00:00 2001 From: onetag-dev <38786435+onetag-dev@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:22:23 +0100 Subject: [PATCH 1/6] Onetag Bid Adapter: add reading of addtlConsent GDPR field (#11202) Co-authored-by: federico --- modules/onetagBidAdapter.js | 3 ++- test/spec/modules/onetagBidAdapter_spec.js | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/onetagBidAdapter.js b/modules/onetagBidAdapter.js index 7a7cbbadd82..d8423253aaf 100644 --- a/modules/onetagBidAdapter.js +++ b/modules/onetagBidAdapter.js @@ -63,7 +63,8 @@ function buildRequests(validBidRequests, bidderRequest) { if (bidderRequest && bidderRequest.gdprConsent) { payload.gdprConsent = { consentString: bidderRequest.gdprConsent.consentString, - consentRequired: bidderRequest.gdprConsent.gdprApplies + consentRequired: bidderRequest.gdprConsent.gdprApplies, + addtlConsent: bidderRequest.gdprConsent.addtlConsent }; } if (bidderRequest && bidderRequest.gppConsent) { diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js index c3d8a4ee0e1..93db5ffc57f 100644 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ b/test/spec/modules/onetagBidAdapter_spec.js @@ -273,6 +273,7 @@ describe('onetag', function () { }); it('should send GDPR consent data', function () { let consentString = 'consentString'; + let addtlConsent = '2~1.35.41.101~dv.9.21.81'; let bidderRequest = { 'bidderCode': 'onetag', 'auctionId': '1d1a030790a475', @@ -280,7 +281,8 @@ describe('onetag', function () { 'timeout': 3000, 'gdprConsent': { consentString: consentString, - gdprApplies: true + gdprApplies: true, + addtlConsent: addtlConsent } }; let serverRequest = spec.buildRequests([bannerBid], bidderRequest); @@ -289,6 +291,7 @@ describe('onetag', function () { expect(payload).to.exist; expect(payload.gdprConsent).to.exist; expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString); + expect(payload.gdprConsent.addtlConsent).to.exist.and.to.equal(addtlConsent); expect(payload.gdprConsent.consentRequired).to.exist.and.to.be.true; }); it('Should send GPP consent data', function () { From 22d10ddf9c7e975f9dc15d7a5f33ff0c11245e38 Mon Sep 17 00:00:00 2001 From: pm-azhar-mulla <75726247+pm-azhar-mulla@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:27:43 +0530 Subject: [PATCH 2/6] PubMatic Analytics Adapter : Logging price bucket value of the bid (#11197) * Logging price bucket value for the bid * Converting data type for logging * Dummy Commit --------- Co-authored-by: pm-azhar-mulla --- modules/pubmaticAnalyticsAdapter.js | 9 +++++++-- test/spec/modules/pubmaticAnalyticsAdapter_spec.js | 13 ++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index 66593a9d72b..ced47086f7b 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -151,6 +151,7 @@ function parseBidResponse(bid) { 'cpm', () => window.parseFloat(Number(bid.cpm).toFixed(BID_PRECISION)), 'originalCpm', () => window.parseFloat(Number(bid.originalCpm).toFixed(BID_PRECISION)), 'originalCurrency', + 'adserverTargeting', 'dealChannel', 'meta', 'status', @@ -278,6 +279,7 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { if (isOWPubmaticBid(adapterName) && isS2SBidder(bid.bidder)) { return; } + const pg = window.parseFloat(Number(bid.bidResponse?.adserverTargeting?.hb_pb || bid.bidResponse?.adserverTargeting?.pwtpb).toFixed(BID_PRECISION)); partnerBids.push({ 'pn': adapterName, 'bc': bid.bidderCode || bid.bidder, @@ -303,7 +305,8 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { 'ocry': bid.bidResponse ? (bid.bidResponse.originalCurrency || CURRENCY_USD) : CURRENCY_USD, 'piid': bid.bidResponse ? (bid.bidResponse.partnerImpId || EMPTY_STRING) : EMPTY_STRING, 'frv': bid.bidResponse ? bid.bidResponse.floorData?.floorRuleValue : undefined, - 'md': bid.bidResponse ? getMetadata(bid.bidResponse.meta) : undefined + 'md': bid.bidResponse ? getMetadata(bid.bidResponse.meta) : undefined, + 'pb': pg || undefined }); }); return partnerBids; @@ -457,8 +460,9 @@ function executeBidWonLoggerCall(auctionId, adUnitId) { let referrer = config.getConfig('pageUrl') || cache.auctions[auctionId].referer || ''; let adv = winningBid.bidResponse ? getAdDomain(winningBid.bidResponse) || undefined : undefined; let fskp = floorData ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined; - + let pg = window.parseFloat(Number(winningBid?.bidResponse?.adserverTargeting?.hb_pb || winningBid?.bidResponse?.adserverTargeting?.pwtpb)) || undefined; let pixelURL = END_POINT_WIN_BID_LOGGER; + pixelURL += 'pubid=' + publisherId; pixelURL += '&purl=' + enc(config.getConfig('pageUrl') || cache.auctions[auctionId].referer || ''); pixelURL += '&tst=' + Math.round((new window.Date()).getTime() / 1000); @@ -475,6 +479,7 @@ function executeBidWonLoggerCall(auctionId, adUnitId) { pixelURL += '&kgpv=' + enc(getValueForKgpv(winningBid, adUnitId)); pixelURL += '&piid=' + enc(winningBid.bidResponse.partnerImpId || EMPTY_STRING); pixelURL += '&di=' + enc(winningBid?.bidResponse?.dealId || OPEN_AUCTION_DEAL_ID); + pixelURL += '&pb=' + enc(pg); pixelURL += '&plt=' + enc(getDevicePlatform()); pixelURL += '&psz=' + enc((winningBid?.bidResponse?.dimensions?.width || '0') + 'x' + diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js index c6447905ecd..951b5135260 100755 --- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js @@ -100,7 +100,7 @@ const BID2 = Object.assign({}, BID, { adserverTargeting: { 'hb_bidder': 'pubmatic', 'hb_adid': '3bd4ebb1c900e2', - 'hb_pb': '1.500', + 'hb_pb': 1.50, 'hb_size': '728x90', 'hb_source': 'server' }, @@ -606,6 +606,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[0].ps[0].ocpm).to.equal(1.23); expect(data.s[0].ps[0].ocry).to.equal('USD'); expect(data.s[0].ps[0].frv).to.equal(1.1); + expect(data.s[0].ps[0].pb).to.equal(1.2); // slot 2 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); expect(data.s[1].fskp).to.equal(0); @@ -640,6 +641,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocpm).to.equal(1.52); expect(data.s[1].ps[0].ocry).to.equal('USD'); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); // tracker slot1 let firstTracker = requests[0].url; @@ -812,6 +814,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[0].ps[0].ocpm).to.equal(1.23); expect(data.s[0].ps[0].ocry).to.equal('USD'); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); // tracker slot1 let firstTracker = requests[0].url; expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); @@ -1035,6 +1038,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocpm).to.equal(1.52); expect(data.s[1].ps[0].ocry).to.equal('USD'); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); }); it('Logger: currency conversion check', function() { @@ -1149,6 +1153,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocpm).to.equal(1.52); expect(data.s[1].ps[0].ocry).to.equal('USD'); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); expect(data.dvc).to.deep.equal({'plt': 2}); // respective tracker slot let firstTracker = requests[1].url; @@ -1209,6 +1214,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocry).to.equal('USD'); expect(data.dvc).to.deep.equal({'plt': 1}); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); // respective tracker slot let firstTracker = requests[1].url; expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); @@ -1267,6 +1273,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocpm).to.equal(1.52); expect(data.s[1].ps[0].ocry).to.equal('USD'); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); // respective tracker slot let firstTracker = requests[1].url; expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); @@ -1388,6 +1395,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocpm).to.equal(1.52); expect(data.s[1].ps[0].ocry).to.equal('USD'); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); }); it('Logger: best case + win tracker in case of Bidder Aliases', function() { @@ -1466,6 +1474,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[0].ps[0].ocpm).to.equal(1.23); expect(data.s[0].ps[0].ocry).to.equal('USD'); expect(data.s[0].ps[0].frv).to.equal(1.1); + expect(data.s[0].ps[0].pb).to.equal(1.2); // slot 2 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); @@ -1501,6 +1510,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[1].ps[0].ocpm).to.equal(1.52); expect(data.s[1].ps[0].ocry).to.equal('USD'); expect(data.s[1].ps[0].frv).to.equal(1.1); + expect(data.s[1].ps[0].pb).to.equal(1.50); // tracker slot1 let firstTracker = requests[0].url; @@ -1596,6 +1606,7 @@ describe('pubmatic analytics adapter', function () { expect(data.s[0].ps[0].ocpm).to.equal(1.23); expect(data.s[0].ps[0].ocry).to.equal('USD'); expect(data.s[0].ps[0].frv).to.equal(1.1); + expect(data.s[0].ps[0].pb).to.equal(1.2); // slot 2 expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); From c9faa28c4a7af5716aec24abd29e181282fa336a Mon Sep 17 00:00:00 2001 From: rishko00 <43280707+rishko00@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:58:02 +0200 Subject: [PATCH 3/6] SmartyadsBidAdapter/add_SGP_region (#11205) Co-authored-by: vrishko --- modules/smartyadsBidAdapter.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/smartyadsBidAdapter.js b/modules/smartyadsBidAdapter.js index 2409bebbc59..b6d5a1711b0 100644 --- a/modules/smartyadsBidAdapter.js +++ b/modules/smartyadsBidAdapter.js @@ -41,8 +41,16 @@ function getAdUrlByRegion(bid) { try { const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const region = timezone.split('/')[0]; - if (region === 'Europe') adUrl = adUrls['EU']; - else adUrl = adUrls['US_EAST']; + + switch (region) { + case 'Europe': + adUrl = adUrls['EU']; + break; + case 'Asia': + adUrl = adUrls['SGP']; + break; + default: adUrl = adUrls['US_EAST']; + } } catch (err) { adUrl = adUrls['US_EAST']; } From b68759d641a7e617b4cc04b38d0dd79c5c66ceca Mon Sep 17 00:00:00 2001 From: Shashank Pradeep <101392500+shashankatd@users.noreply.github.com> Date: Wed, 13 Mar 2024 23:17:49 +0530 Subject: [PATCH 4/6] Automatad Analytics Adapter : expose queue as a global object (#11203) * fix: added fix for automatadAnalytics * fix: add s3 upload for atmtd * fix: add upload to s3 * fix: removed changes to gulp file and package.json * fix: added build command to gulp * fix: removed extra line from gulpfile * restored original gulp file * fix: minor fix to condition * fix: removed unnecessary condition * fix: removed linting error * Get build check to re run --------- Co-authored-by: Shashank <=> --- modules/automatadAnalyticsAdapter.js | 53 ++++---- .../modules/automatadAnalyticsAdapter_spec.js | 117 +++++++++++++++--- 2 files changed, 133 insertions(+), 37 deletions(-) diff --git a/modules/automatadAnalyticsAdapter.js b/modules/automatadAnalyticsAdapter.js index 7d7bd8cb34c..436418e7597 100644 --- a/modules/automatadAnalyticsAdapter.js +++ b/modules/automatadAnalyticsAdapter.js @@ -14,7 +14,7 @@ import { config } from '../src/config.js' const ADAPTER_CODE = 'automatadAnalytics' const trialCountMilsMapping = [1500, 3000, 5000, 10000]; -var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null; var __atmtdAnalyticsQueue = []; +var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null; var __atmtdAnalyticsQueue = []; var qBeingUsed; var qTraversalComplete; const prettyLog = (level, text, isGroup = false, cb = () => {}) => { if (self.isLoggingEnabled === undefined) { @@ -134,6 +134,9 @@ const processEvents = () => { if (trialCountMilsMapping[self.retryCount]) self.prettyLog('warn', `Adapter failed to process event as aggregator has not loaded. Retrying in ${trialCountMilsMapping[self.retryCount]}ms ...`); setTimeout(self.processEvents, trialCountMilsMapping[self.retryCount]) self.retryCount = self.retryCount + 1 + } else { + self.qBeingUsed = false + self.qTraversalComplete = true } } @@ -142,22 +145,18 @@ const addGPTHandlers = () => { googletag.cmd = googletag.cmd || [] googletag.cmd.push(() => { googletag.pubads().addEventListener('slotRenderEnded', (event) => { - if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler) { - if (window.__atmtdAggregatorFirstAuctionInitialized === true) { - window.atmtdAnalytics.slotRenderEndedGPTHandler(event) - return; - } + if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler && !self.qBeingUsed) { + window.atmtdAnalytics.slotRenderEndedGPTHandler(event) + return; } self.__atmtdAnalyticsQueue.push(['slotRenderEnded', event]) self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting slotRenderEnded handler and pushing to que instead`) }) googletag.pubads().addEventListener('impressionViewable', (event) => { - if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler) { - if (window.__atmtdAggregatorFirstAuctionInitialized === true) { - window.atmtdAnalytics.impressionViewableHandler(event) - return; - } + if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler && !self.qBeingUsed) { + window.atmtdAnalytics.impressionViewableHandler(event) + return; } self.__atmtdAnalyticsQueue.push(['impressionViewable', event]) self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting impressionViewable handler and pushing to que instead`) @@ -167,6 +166,7 @@ const addGPTHandlers = () => { const initializeQueue = () => { self.__atmtdAnalyticsQueue.push = (args) => { + self.qBeingUsed = true Array.prototype.push.apply(self.__atmtdAnalyticsQueue, [args]); if (timer) { clearTimeout(timer); @@ -196,9 +196,10 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { }, track({eventType, args}) { + const shouldNotPushToQueue = !self.qBeingUsed switch (eventType) { case CONSTANTS.EVENTS.AUCTION_INIT: - if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler && shouldNotPushToQueue) { self.prettyLog('status', 'Aggregator loaded, initialising auction through handlers'); window.atmtdAnalytics.auctionInitHandler(args); } else { @@ -207,7 +208,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.BID_REQUESTED: - if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler && shouldNotPushToQueue) { window.atmtdAnalytics.bidRequestedHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -215,7 +216,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.BID_REJECTED: - if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler && shouldNotPushToQueue) { window.atmtdAnalytics.bidRejectedHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -223,7 +224,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.BID_RESPONSE: - if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler && shouldNotPushToQueue) { window.atmtdAnalytics.bidResponseHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -231,7 +232,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.BIDDER_DONE: - if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler && shouldNotPushToQueue) { window.atmtdAnalytics.bidderDoneHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -239,7 +240,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.BID_WON: - if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler && shouldNotPushToQueue) { window.atmtdAnalytics.bidWonHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -247,7 +248,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.NO_BID: - if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler && shouldNotPushToQueue) { window.atmtdAnalytics.noBidHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -255,7 +256,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.AUCTION_DEBUG: - if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler && shouldNotPushToQueue) { window.atmtdAnalytics.auctionDebugHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -263,7 +264,7 @@ let atmtdAdapter = Object.assign({}, baseAdapter, { } break; case CONSTANTS.EVENTS.BID_TIMEOUT: - if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler) { + if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler && shouldNotPushToQueue) { window.atmtdAnalytics.bidderTimeoutHandler(args); } else { self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`); @@ -304,7 +305,7 @@ atmtdAdapter.enableAnalytics = function (configuration) { atmtdAdapter.originEnableAnalytics(configuration) }; -/// /////////// ADAPTER REGISTRATION ////////////// +/// /////////// ADAPTER REGISTRATION ///////////// adapterManager.registerAnalyticsAdapter({ adapter: atmtdAdapter, @@ -319,7 +320,15 @@ export var self = { prettyLog, queuePointer, retryCount, - isLoggingEnabled + isLoggingEnabled, + qBeingUsed, + qTraversalComplete +} + +window.__atmtdAnalyticsGlobalObject = { + q: self.__atmtdAnalyticsQueue, + qBeingUsed: self.qBeingUsed, + qTraversalComplete: self.qTraversalComplete } export default atmtdAdapter; diff --git a/test/spec/modules/automatadAnalyticsAdapter_spec.js b/test/spec/modules/automatadAnalyticsAdapter_spec.js index e591f7e8e95..a7dd28a8dc0 100644 --- a/test/spec/modules/automatadAnalyticsAdapter_spec.js +++ b/test/spec/modules/automatadAnalyticsAdapter_spec.js @@ -6,6 +6,18 @@ import spec, {self as exports} from 'modules/automatadAnalyticsAdapter.js'; import CONSTANTS from 'src/constants.json'; import { expect } from 'chai'; +const obj = { + auctionInitHandler: (args) => {}, + bidResponseHandler: (args) => {}, + bidderDoneHandler: (args) => {}, + bidWonHandler: (args) => {}, + noBidHandler: (args) => {}, + auctionDebugHandler: (args) => {}, + bidderTimeoutHandler: (args) => {}, + bidRequestedHandler: (args) => {}, + bidRejectedHandler: (args) => {} +} + const { AUCTION_DEBUG, BID_REQUESTED, @@ -117,20 +129,10 @@ describe('Automatad Analytics Adapter', () => { describe('Behaviour of the adapter when the sdk has loaded', () => { before(() => { spec.enableAnalytics(CONFIG_WITH_DEBUG); - const obj = { - auctionInitHandler: (args) => {}, - bidResponseHandler: (args) => {}, - bidderDoneHandler: (args) => {}, - bidWonHandler: (args) => {}, - noBidHandler: (args) => {}, - auctionDebugHandler: (args) => {}, - bidderTimeoutHandler: (args) => {}, - bidRequestedHandler: (args) => {}, - bidRejectedHandler: (args) => {} - } global.window.atmtdAnalytics = obj - + exports.qBeingUsed = false + exports.qTraversalComplete = undefined Object.keys(obj).forEach((fn) => sandbox.spy(global.window.atmtdAnalytics, fn)) }) beforeEach(() => { @@ -143,8 +145,12 @@ describe('Automatad Analytics Adapter', () => { sandbox.restore(); }); after(() => { + const handlers = global.window.atmtdAnalytics + Object.keys(handlers).forEach((handler) => global.window.atmtdAnalytics[handler].reset()) global.window.atmtdAnalytics = undefined; spec.disableAnalytics(); + exports.qBeingUsed = false + exports.qTraversalComplete = undefined }) it('Should call the auctionInitHandler when the auction init event is fired', () => { @@ -298,6 +304,85 @@ describe('Automatad Analytics Adapter', () => { }); }); + describe('Behaviour of the adapter when the SDK has loaded midway', () => { + before(() => { + spec.enableAnalytics(CONFIG_WITH_DEBUG); + }) + beforeEach(() => { + sandbox = sinon.createSandbox(); + + global.window.atmtdAnalytics = undefined + + exports.qBeingUsed = undefined + exports.qTraversalComplete = undefined + exports.queuePointer = 0 + exports.retryCount = 0 + exports.__atmtdAnalyticsQueue.length = 0 + + clock = sandbox.useFakeTimers(); + + sandbox.spy(exports.__atmtdAnalyticsQueue, 'push') + }); + afterEach(() => { + sandbox.restore(); + }); + after(() => { + spec.disableAnalytics(); + }) + + it('Should push to the que when the auctionInit event is fired and push to the que even after SDK has loaded after auctionInit event', () => { + events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) + expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) + expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) + expect(exports.__atmtdAnalyticsQueue[0][0]).to.equal(BID_RESPONSE) + expect(exports.__atmtdAnalyticsQueue[0][1].type).to.equal(BID_RESPONSE) + expect(exports.qBeingUsed).to.equal(true) + expect(exports.qTraversalComplete).to.equal(undefined) + global.window.atmtdAnalytics = obj + events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true) + expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2) + expect(exports.__atmtdAnalyticsQueue[1]).to.have.lengthOf(2) + expect(exports.__atmtdAnalyticsQueue[1][0]).to.equal(BID_RESPONSE) + expect(exports.__atmtdAnalyticsQueue[1][1].type).to.equal(BID_RESPONSE) + expect(exports.qBeingUsed).to.equal(true) + expect(exports.qTraversalComplete).to.equal(undefined) + }); + + it('Should push to the que when the auctionInit event is fired and push to the analytics adapter handler after the que is processed', () => { + expect(exports.qBeingUsed).to.equal(undefined) + events.emit(AUCTION_INIT, {type: AUCTION_INIT}) + global.window.atmtdAnalytics = {...obj} + const handlers = global.window.atmtdAnalytics + Object.keys(handlers).forEach((handler) => global.window.atmtdAnalytics[handler].reset()) + expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) + expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) + expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) + expect(exports.__atmtdAnalyticsQueue[0][0]).to.equal(AUCTION_INIT) + expect(exports.__atmtdAnalyticsQueue[0][1].type).to.equal(AUCTION_INIT) + expect(exports.qBeingUsed).to.equal(true) + expect(exports.qTraversalComplete).to.equal(undefined) + expect(global.window.atmtdAnalytics.auctionInitHandler.callCount).to.equal(0) + clock.tick(2000) + expect(exports.qBeingUsed).to.equal(true) + expect(exports.qTraversalComplete).to.equal(undefined) + events.emit(NO_BID, {type: NO_BID}) + expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2) + expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true) + clock.tick(1500) + expect(exports.qBeingUsed).to.equal(false) + expect(exports.qTraversalComplete).to.equal(true) + events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2) + expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true) + expect(exports.__atmtdAnalyticsQueue.push.calledThrice).to.equal(false) + expect(global.window.atmtdAnalytics.auctionInitHandler.calledOnce).to.equal(true) + expect(global.window.atmtdAnalytics.noBidHandler.calledOnce).to.equal(true) + expect(global.window.atmtdAnalytics.bidResponseHandler.calledOnce).to.equal(true) + }); + }); + describe('Process Events from Que when SDK still has not loaded', () => { before(() => { spec.enableAnalytics({ @@ -312,6 +397,8 @@ describe('Automatad Analytics Adapter', () => { sandbox.stub(exports.__atmtdAnalyticsQueue, 'push').callsFake((args) => { Array.prototype.push.apply(exports.__atmtdAnalyticsQueue, [args]); }) + exports.queuePointer = 0; + exports.retryCount = 0; }) beforeEach(() => { sandbox = sinon.createSandbox(); @@ -326,7 +413,6 @@ describe('Automatad Analytics Adapter', () => { sandbox.restore(); exports.queuePointer = 0; exports.retryCount = 0; - exports.__atmtdAnalyticsQueue = [] spec.disableAnalytics(); }) @@ -437,7 +523,6 @@ describe('Automatad Analytics Adapter', () => { } }); sandbox = sinon.createSandbox(); - sandbox.reset() const obj = { auctionInitHandler: (args) => {}, bidResponseHandler: (args) => {}, @@ -473,8 +558,10 @@ describe('Automatad Analytics Adapter', () => { ['impressionViewable', {type: 'impressionViewable'}] ] }); - after(() => { + afterEach(() => { sandbox.restore(); + }) + after(() => { spec.disableAnalytics(); }) From 1c57789be9a6c8e451eb27886999d85822b84b29 Mon Sep 17 00:00:00 2001 From: barRubi <151519394+barRubi@users.noreply.github.com> Date: Wed, 13 Mar 2024 23:48:11 +0200 Subject: [PATCH 5/6] Taboola Bid Adapter : providing visibility in case of bid error (#11195) * cookie-look-up-logic-fix-gpp-fix * refactor using ORTB conversion library --------- Co-authored-by: ahmadlob <109217988+ahmadlob@users.noreply.github.com> Co-authored-by: Ahmad Lobany Co-authored-by: aleskanderl <109285067+aleskanderl@users.noreply.github.com> --- modules/taboolaBidAdapter.js | 2 +- test/spec/modules/taboolaBidAdapter_spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/taboolaBidAdapter.js b/modules/taboolaBidAdapter.js index b0418ab9865..3b26a00c6fb 100644 --- a/modules/taboolaBidAdapter.js +++ b/modules/taboolaBidAdapter.js @@ -200,7 +200,7 @@ export const spec = { }, onBidderError: ({ error, bidderRequest }) => { - ajax(EVENT_ENDPOINT + '/bidError', null, JSON.stringify(error, bidderRequest), {method: 'POST'}); + ajax(EVENT_ENDPOINT + '/bidError', null, JSON.stringify({error, bidderRequest}), {method: 'POST'}); }, }; diff --git a/test/spec/modules/taboolaBidAdapter_spec.js b/test/spec/modules/taboolaBidAdapter_spec.js index 39df2eb4a99..958cd668f63 100644 --- a/test/spec/modules/taboolaBidAdapter_spec.js +++ b/test/spec/modules/taboolaBidAdapter_spec.js @@ -157,7 +157,7 @@ describe('Taboola Adapter', function () { spec.onBidderError({error, bidderRequest}); expect(server.requests[0].method).to.equal('POST'); expect(server.requests[0].url).to.equal(EVENT_ENDPOINT + '/bidError'); - expect(JSON.parse(server.requests[0].requestBody)).to.deep.equal(error, bidderRequest); + expect(JSON.parse(server.requests[0].requestBody)).to.deep.equal({error, bidderRequest}); }); }); From 77254c2954d61c9156735a2fb30611fd7bbde6e4 Mon Sep 17 00:00:00 2001 From: Saurabh Joshi <43156540+sj1815@users.noreply.github.com> Date: Thu, 14 Mar 2024 04:49:56 -0400 Subject: [PATCH 6/6] Kargo Bid Adapter: floors and CreativeID update (#11153) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * KargoBidAdapter: GPP Support * kargo adapter to forward schain object (#21) * wrap in if statement (#22) * KRKPD-572: Add spec for schain (#23) * wrap in if statement * update test for schain, file formatting * Adding site to Kargo adapter. * KRKPD-619 Updating Site object. * KRKPD-619 Adding null check for Site object. * Update modules/kargoBidAdapter.js Co-authored-by: Julian Gan * Reducing the size of Site object. * remove white space that is causing linting error * Kargo Bid Adapter: Updates to gpid retrieval * Support for sending ortb2.user.data * update bid Response to use actual creativeID * update spec * fix nomencalature based on Kargo's service * Prebid.js - Update bid Response to use actual creativeID (#25) * update bid Response to use actual creativeID * update spec * fix nomencalature based on Kargo's service * utilize floors mod * fixes tests * mediatype specific floors * simpler implementation leveraging Prebid's smart rule selection * revert nomenclature change * fix * removes comment --------- Co-authored-by: Jeremy Sadwith Co-authored-by: Julian Gan Co-authored-by: Neil Flynn Co-authored-by: “Nick <“nick.llerandi”@kargo.com> Co-authored-by: Nick Llerandi --- modules/kargoBidAdapter.js | 38 +++++++++++++-------- test/spec/modules/kargoBidAdapter_spec.js | 40 ++++++++++++++++------- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js index 9d8c7bc06a1..b72601e5ebb 100644 --- a/modules/kargoBidAdapter.js +++ b/modules/kargoBidAdapter.js @@ -1,4 +1,4 @@ -import { _each, isEmpty, buildUrl, deepAccess, pick, triggerPixel } from '../src/utils.js'; +import { _each, isEmpty, buildUrl, deepAccess, pick, triggerPixel, logError } from '../src/utils.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -221,7 +221,7 @@ function interpretResponse(response, bidRequest) { width: adUnit.width, height: adUnit.height, ttl: 300, - creativeId: adUnit.id, + creativeId: adUnit.creativeID, dealId: adUnit.targetingCustom, netRevenue: true, currency: adUnit.currency || bidRequest.currency, @@ -459,10 +459,6 @@ function getImpression(bid) { code: bid.adUnitCode }; - if (bid.floorData != null && bid.floorData.floorMin > 0) { - imp.floor = bid.floorData.floorMin; - } - if (bid.bidRequestsCount > 0) { imp.bidRequestCount = bid.bidRequestsCount; } @@ -482,17 +478,33 @@ function getImpression(bid) { } } - if (bid.mediaTypes != null) { - if (bid.mediaTypes.banner != null) { - imp.banner = bid.mediaTypes.banner; + if (bid.mediaTypes) { + const { banner, video, native } = bid.mediaTypes; + + if (banner) { + imp.banner = banner; } - if (bid.mediaTypes.video != null) { - imp.video = bid.mediaTypes.video; + if (video) { + imp.video = video; } - if (bid.mediaTypes.native != null) { - imp.native = bid.mediaTypes.native; + if (native) { + imp.native = native; + } + + if (typeof bid.getFloor === 'function') { + let floorInfo; + try { + floorInfo = bid.getFloor({ + currency: 'USD', + mediaType: '*', + size: '*' + }); + } catch (e) { + logError('Kargo: getFloor threw an error: ', e); + } + imp.floor = typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseInt(floorInfo.floor)) ? floorInfo.floor : undefined; } } diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js index f43c3b11aac..40f8833c6ec 100644 --- a/test/spec/modules/kargoBidAdapter_spec.js +++ b/test/spec/modules/kargoBidAdapter_spec.js @@ -491,7 +491,8 @@ describe('kargo adapter tests', function () { }, fpd: { gpid: '/22558409563,18834096/dfy_mobile_adhesion' - } + }, + floor: 2 }, { code: '303', @@ -503,7 +504,8 @@ describe('kargo adapter tests', function () { }, fpd: { gpid: '/22558409563,18834096/dfy_mobile_adhesion' - } + }, + floor: 3 } ], socan: { @@ -605,6 +607,16 @@ describe('kargo adapter tests', function () { payload['gdprConsent'] = gdpr } + clonedBids.forEach(bid => { + if (bid.mediaTypes.banner) { + bid.getFloor = () => ({ currency: 'USD', floor: 1 }); + } else if (bid.mediaTypes.video) { + bid.getFloor = () => ({ currency: 'USD', floor: 2 }); + } else if (bid.mediaTypes.native) { + bid.getFloor = () => ({ currency: 'USD', floor: 3 }); + } + }); + var request = spec.buildRequests(clonedBids, payload); var krakenParams = request.data; @@ -725,7 +737,8 @@ describe('kargo adapter tests', function () { adm: '
', width: 320, height: 50, - metadata: {} + metadata: {}, + creativeID: 'bar' }, 2: { id: 'bar', @@ -736,14 +749,16 @@ describe('kargo adapter tests', function () { targetingCustom: 'dmpmptest1234', metadata: { landingPageDomain: ['https://foobar.com'] - } + }, + creativeID: 'foo' }, 3: { id: 'bar', cpm: 2.5, adm: '
', width: 300, - height: 250 + height: 250, + creativeID: 'foo' }, 4: { id: 'bar', @@ -753,6 +768,7 @@ describe('kargo adapter tests', function () { height: 250, mediaType: 'banner', metadata: {}, + creativeID: 'foo', currency: 'EUR' }, 5: { @@ -763,6 +779,7 @@ describe('kargo adapter tests', function () { height: 250, mediaType: 'video', metadata: {}, + creativeID: 'foo', currency: 'EUR' }, 6: { @@ -774,6 +791,7 @@ describe('kargo adapter tests', function () { height: 250, mediaType: 'video', metadata: {}, + creativeID: 'foo', currency: 'EUR' } } @@ -818,7 +836,7 @@ describe('kargo adapter tests', function () { width: 320, height: 50, ttl: 300, - creativeId: 'foo', + creativeId: 'bar', dealId: undefined, netRevenue: true, currency: 'USD', @@ -833,7 +851,7 @@ describe('kargo adapter tests', function () { width: 300, height: 250, ttl: 300, - creativeId: 'bar', + creativeId: 'foo', dealId: 'dmpmptest1234', netRevenue: true, currency: 'USD', @@ -850,7 +868,7 @@ describe('kargo adapter tests', function () { width: 300, height: 250, ttl: 300, - creativeId: 'bar', + creativeId: 'foo', dealId: undefined, netRevenue: true, currency: 'USD', @@ -865,7 +883,7 @@ describe('kargo adapter tests', function () { width: 300, height: 250, ttl: 300, - creativeId: 'bar', + creativeId: 'foo', dealId: undefined, netRevenue: true, currency: 'EUR', @@ -880,7 +898,7 @@ describe('kargo adapter tests', function () { height: 250, vastXml: '', ttl: 300, - creativeId: 'bar', + creativeId: 'foo', dealId: undefined, netRevenue: true, currency: 'EUR', @@ -895,7 +913,7 @@ describe('kargo adapter tests', function () { height: 250, vastUrl: 'https://foobar.com/vast_adm', ttl: 300, - creativeId: 'bar', + creativeId: 'foo', dealId: undefined, netRevenue: true, currency: 'EUR',