diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 136cf6f25f0..7d3b3a33a7d 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -1053,9 +1053,14 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { currentImpressionSize = encodeURIComponent(JSON.stringify({ impressionObjects })).length; } - const gpid = impressions[transactionIds[adUnitIndex]].gpid; + let gpid = impressions[transactionIds[adUnitIndex]].gpid; const dfpAdUnitCode = impressions[transactionIds[adUnitIndex]].dfp_ad_unit_code; - const tid = impressions[transactionIds[adUnitIndex]].tid + const tid = impressions[transactionIds[adUnitIndex]].tid; + const divId = impressions[transactionIds[adUnitIndex]].divId; + + if (!gpid && dfpAdUnitCode && divId) { + gpid = `${dfpAdUnitCode}#${divId}` + } if (impressionObjects.length && BANNER in impressionObjects[0]) { const { id, banner: { topframe } } = impressionObjects[0]; const _bannerImpression = { @@ -1135,7 +1140,6 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) { const pbaAdSlot = impressions[transactionIds[adUnitIndex]].pbadslot const tagId = impressions[transactionIds[adUnitIndex]].tagId const adUnitCode = impressions[transactionIds[adUnitIndex]].adUnitCode - const divId = impressions[transactionIds[adUnitIndex]].divId if (pbaAdSlot || tagId || adUnitCode || divId) { const clonedRObject = deepClone(r); const requestSize = `${baseUrl}${parseQueryStringParameters({ ...payload, r: JSON.stringify(clonedRObject) })}`.length; @@ -1279,7 +1283,8 @@ function createNativeImps(validBidRequest, nativeImps) { nativeImps[validBidRequest.transactionId] = {}; nativeImps[validBidRequest.transactionId].ixImps = []; nativeImps[validBidRequest.transactionId].ixImps.push(imp); - nativeImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid') + nativeImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid'); + nativeImps[validBidRequest.transactionId].dfp_ad_unit_code = deepAccess(validBidRequest, 'ortb2Imp.ext.data.adserver.adslot'); nativeImps[validBidRequest.transactionId].pbadslot = deepAccess(validBidRequest, 'ortb2Imp.ext.data.pbadslot'); nativeImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId'); @@ -1302,6 +1307,7 @@ function createVideoImps(validBidRequest, videoImps) { videoImps[validBidRequest.transactionId].ixImps = []; videoImps[validBidRequest.transactionId].ixImps.push(imp); videoImps[validBidRequest.transactionId].gpid = deepAccess(validBidRequest, 'ortb2Imp.ext.gpid'); + videoImps[validBidRequest.transactionId].dfp_ad_unit_code = deepAccess(validBidRequest, 'ortb2Imp.ext.data.adserver.adslot'); videoImps[validBidRequest.transactionId].pbadslot = deepAccess(validBidRequest, 'ortb2Imp.ext.data.pbadslot'); videoImps[validBidRequest.transactionId].tagId = deepAccess(validBidRequest, 'params.tagId'); @@ -1651,7 +1657,17 @@ export const spec = { } if (mediaTypeVideoRef && paramsVideoRef) { + const videoImp = bidToVideoImp(bid).video; const errorList = checkVideoParams(mediaTypeVideoRef, paramsVideoRef); + if (deepAccess(bid, 'mediaTypes.video.context') === OUTSTREAM && isIndexRendererPreferred(bid) && videoImp) { + const outstreamPlayerSize = [deepAccess(videoImp, 'w'), deepAccess(videoImp, 'h')]; + const isValidSize = outstreamPlayerSize[0] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[0] && outstreamPlayerSize[1] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[1]; + if (!isValidSize) { + logError(`IX Bid Adapter: ${outstreamPlayerSize} is an invalid size for IX outstream renderer`); + return false; + } + } + if (errorList.length) { errorList.forEach((err) => { logError(err, { bidder: BIDDER_CODE, code: ERROR_CODES.PROPERTY_NOT_INCLUDED }); @@ -1660,16 +1676,6 @@ export const spec = { } } - const videoImp = bidToVideoImp(bid).video; - if (deepAccess(bid, 'mediaTypes.video.context') === OUTSTREAM && isIndexRendererPreferred(bid) && videoImp) { - const outstreamPlayerSize = [deepAccess(videoImp, 'w'), deepAccess(videoImp, 'h')]; - const isValidSize = outstreamPlayerSize[0] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[0] && outstreamPlayerSize[1] >= OUTSTREAM_MINIMUM_PLAYER_SIZE[1]; - if (!isValidSize) { - logError(`IX Bid Adapter: ${outstreamPlayerSize} is an invalid size for IX outstream renderer`); - return false; - } - } - return nativeMediaTypeValid(mediaTypeNativeRef); }, diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index a25e6b1c6a0..086ec305ccc 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -1657,6 +1657,70 @@ describe('IndexexchangeAdapter', function () { expect(gpid).to.equal(GPID); }); + it('should still build gpid in request if ortb2Imp.ext.gpid does not exist', function () { + const AD_UNIT_CODE = '/1111/home'; + const validBids = utils.deepClone(DEFAULT_BANNER_VALID_BID); + sinon.stub(utils, 'getGptSlotInfoForAdUnitCode') + .returns({ gptSlot: AD_UNIT_CODE, divId: 'adunit-code-3-div-id' }); + validBids[0].ortb2Imp = { + ext: { + data: { + adserver: { + name: 'gam', + adslot: AD_UNIT_CODE + } + } + } + } + const requests = spec.buildRequests(validBids, DEFAULT_OPTION); + const { ext: { gpid } } = JSON.parse(requests[0].data.r).imp[0]; + utils.getGptSlotInfoForAdUnitCode.restore(); + expect(gpid).to.equal(`${AD_UNIT_CODE}#adunit-code-3-div-id`); + }); + + it('should not build gpid if divid doesnt exist when ortb2Imp.ext.gpid does not exist', function () { + const AD_UNIT_CODE = '/1111/home'; + const validBids = utils.deepClone(DEFAULT_BANNER_VALID_BID); + sinon.stub(utils, 'getGptSlotInfoForAdUnitCode') + .returns({ gptSlot: AD_UNIT_CODE }); + validBids[0].ortb2Imp = { + ext: { + data: { + adserver: { + name: 'gam', + adslot: AD_UNIT_CODE + } + } + } + } + const requests = spec.buildRequests(validBids, DEFAULT_OPTION); + const imp = JSON.parse(requests[0].data.r).imp[0]; + utils.getGptSlotInfoForAdUnitCode.restore(); + expect(imp.ext.gpid).to.be.undefined; + expect(imp.ext.dfp_ad_unit_code).to.equal(AD_UNIT_CODE) + }); + + it('should not build gpid if dfp ad unit code / divid doesnt exist when ortb2Imp.ext.gpid does not exist', function () { + const AD_UNIT_CODE = '/1111/home'; + const validBids = utils.deepClone(DEFAULT_BANNER_VALID_BID); + sinon.stub(utils, 'getGptSlotInfoForAdUnitCode') + .returns({}); + validBids[0].ortb2Imp = { + ext: { + data: { + adserver: { + name: 'gam', + } + } + } + } + const requests = spec.buildRequests(validBids, DEFAULT_OPTION); + + const imp = JSON.parse(requests[0].data.r).imp[0]; + utils.getGptSlotInfoForAdUnitCode.restore(); + expect(imp.ext).to.be.undefined; + }); + it('should send gpid in request if ortb2Imp.ext.gpid exists when no size present', function () { const validBids = utils.deepClone(DEFAULT_BANNER_VALID_BID_PARAM_NO_SIZE); validBids[0].ortb2Imp = {