diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index 9e1fa49fef2..e54db34d401 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -281,7 +281,7 @@ function isOWPubmaticBid(adapterName) { }) } -function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { +function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid, e) { highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null; return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) { adUnit.bids[bidId].forEach(function(bid) { @@ -290,6 +290,16 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { return; } const pg = window.parseFloat(Number(bid.bidResponse?.adserverTargeting?.hb_pb || bid.bidResponse?.adserverTargeting?.pwtpb).toFixed(BID_PRECISION)); + + const prebidBidsReceived = e?.bidsReceived; + if (isArray(prebidBidsReceived) && prebidBidsReceived.length > 0) { + prebidBidsReceived.forEach(function(iBid) { + if (iBid.adId === bid.adId) { + bid.bidderCode = iBid.bidderCode; + } + }); + } + partnerBids.push({ 'pn': adapterName, 'bc': bid.bidderCode || bid.bidder, @@ -391,7 +401,7 @@ function executeBidsLoggerCall(e, highestCpmBids) { outputObj['pdvid'] = '' + profileVersionId; outputObj['dvc'] = {'plt': getDevicePlatform()}; outputObj['tgid'] = getTgId(); - outputObj['pbv'] = getGlobal()?.version || '-1'; + outputObj['pbv'] = '$prebid.version$' || '-1'; if (floorData && floorFetchStatus) { outputObj['fmv'] = floorData.floorRequestData ? floorData.floorRequestData.modelVersion || undefined : undefined; @@ -407,7 +417,7 @@ function executeBidsLoggerCall(e, highestCpmBids) { 'au': origAdUnit.owAdUnitId || getGptSlotInfoForAdUnitCode(adUnitId)?.gptSlot || adUnitId, 'mt': getAdUnitAdFormats(origAdUnit), 'sz': getSizesForAdUnit(adUnit, adUnitId), - 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)), + 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId), e), 'fskp': floorData && floorFetchStatus ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined, 'sid': generateUUID() }; @@ -559,7 +569,8 @@ function bidResponseHandler(args) { logWarn(LOG_PRE_FIX + 'Got null requestId in bidResponseHandler'); return; } - let bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId][0]; + let requestId = args.originalRequestId || args.requestId; + let bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[requestId][0]; if (!bid) { logError(LOG_PRE_FIX + 'Could not find associated bid request for bid response with requestId: ', args.requestId); return; @@ -567,7 +578,9 @@ function bidResponseHandler(args) { if ((bid.bidder && args.bidderCode && bid.bidder !== args.bidderCode) || (bid.bidder === args.bidderCode && bid.status === SUCCESS)) { bid = copyRequiredBidDetails(args); - cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId].push(bid); + cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[requestId].push(bid); + } else if (args.originalRequestId) { + bid.bidId = args.requestId; } if (args.floorData) { @@ -598,7 +611,7 @@ function bidRejectedHandler(args) { function bidderDoneHandler(args) { cache.auctions[args.auctionId].bidderDonePendingCount--; args.bids.forEach(bid => { - let cachedBid = cache.auctions[bid.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId || bid.requestId]; + let cachedBid = cache.auctions[bid.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId || bid.originalRequestId || bid.requestId]; if (typeof bid.serverResponseTimeMs !== 'undefined') { cachedBid.serverLatencyTimeMs = bid.serverResponseTimeMs; } @@ -613,7 +626,7 @@ function bidderDoneHandler(args) { function bidWonHandler(args) { let auctionCache = cache.auctions[args.auctionId]; - auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.requestId; + auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.originalRequestId || args.requestId; auctionCache.adUnitCodes[args.adUnitCode].bidWonAdId = args.adId; executeBidWonLoggerCall(args.auctionId, args.adUnitCode); } @@ -631,7 +644,7 @@ function bidTimeoutHandler(args) { // db = 0 and t = 1 means bidder did respond with a bid but post timeout args.forEach(badBid => { let auctionCache = cache.auctions[badBid.auctionId]; - let bid = auctionCache.adUnitCodes[badBid.adUnitCode].bids[ badBid.bidId || badBid.requestId ][0]; + let bid = auctionCache.adUnitCodes[badBid.adUnitCode].bids[ badBid.bidId || badBid.originalRequestId || badBid.requestId ][0]; if (bid) { bid.status = ERROR; bid.error = { diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js index 002b7fb3063..f77b167a3e9 100755 --- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js @@ -568,7 +568,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tgid).to.equal(15); expect(data.fmv).to.equal('floorModelTest'); expect(data.ft).to.equal(1); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); // slot 1 @@ -786,7 +786,7 @@ describe('pubmatic analytics adapter', function () { expect(data.pid).to.equal('1111'); expect(data.fmv).to.equal('floorModelTest'); expect(data.ft).to.equal(1); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); expect(data.tgid).to.equal(0); @@ -866,7 +866,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tgid).to.equal(0);// test group id should be between 0-15 else set to 0 expect(data.fmv).to.equal('floorModelTest'); expect(data.ft).to.equal(1); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); // slot 1 @@ -1434,7 +1434,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tst).to.equal(1519767016); expect(data.tgid).to.equal(15); expect(data.fmv).to.equal('floorModelTest'); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.ft).to.equal(1); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); @@ -1566,7 +1566,7 @@ describe('pubmatic analytics adapter', function () { expect(data.tst).to.equal(1519767016); expect(data.tgid).to.equal(15); expect(data.fmv).to.equal('floorModelTest'); - expect(data.pbv).to.equal(getGlobal()?.version || '-1'); + expect(data.pbv).to.equal('$prebid.version$' || '-1'); expect(data.ft).to.equal(1); expect(data.s).to.be.an('array'); expect(data.s.length).to.equal(2); @@ -1657,8 +1657,55 @@ describe('pubmatic analytics adapter', function () { expect(data.origbidid).to.equal('partnerImpressionID-1'); }); + it('Logger: should use originalRequestId to find the bid', function() { + MOCK.BID_RESPONSE[1]['originalRequestId'] = '3bd4ebb1c900e2'; + MOCK.BID_RESPONSE[1]['requestId'] = '54d4ebb1c9003e'; + sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { + return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]] + }); + + config.setConfig({ + testGroupId: 15 + }); + + events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); + events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); + events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); + events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); + events.emit(AUCTION_END, MOCK.AUCTION_END); + events.emit(SET_TARGETING, MOCK.SET_TARGETING); + events.emit(BID_WON, MOCK.BID_WON[0]); + events.emit(BID_WON, MOCK.BID_WON[1]); + + clock.tick(2000 + 1000); + expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker + let request = requests[2]; // logger is executed late, trackers execute first + expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); + let data = getLoggerJsonFromRequest(request.requestBody); + expect(data.s).to.be.an('array'); + expect(data.s.length).to.equal(2); + + // slot 1 + expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); + expect(data.s[0].ps[0].origbidid).to.equal('partnerImpressionID-1'); + + // slot 2 + expect(data.s[1].ps[0].bidid).to.equal('54d4ebb1c9003e'); + expect(data.s[1].ps[0].origbidid).to.equal('partnerImpressionID-2'); + + // tracker slot1 + let firstTracker = requests[0].url; + expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); + data = {}; + firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); + expect(data.bidid).to.equal('2ecff0db240757'); + expect(data.origbidid).to.equal('partnerImpressionID-1'); + }); + it('Logger: best case + win tracker. Log bidId when partnerimpressionid is missing', function() { delete MOCK.BID_RESPONSE[1]['partnerImpId']; + MOCK.BID_RESPONSE[1]['requestId'] = '3bd4ebb1c900e2'; MOCK.BID_RESPONSE[1]['prebidBidId'] = 'Prebid-bid-id-1'; sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]]