Skip to content

Commit

Permalink
í°� fix bug for interpreting bid response without zone id provided in…
Browse files Browse the repository at this point in the history
… request (#10288)

Co-authored-by: v.raybaud <v.raybaud@criteo.com>
  • Loading branch information
vraybaud and v.raybaud authored Aug 8, 2023
1 parent 1b8cd38 commit 5249b47
Show file tree
Hide file tree
Showing 2 changed files with 265 additions and 42 deletions.
106 changes: 64 additions & 42 deletions modules/criteoBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { loadExternalScript } from '../src/adloader.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { config } from '../src/config.js';
import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
import { find } from '../src/polyfill.js';
import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; // ref#2
import { getStorageManager } from '../src/storageManager.js';
import { getRefererInfo } from '../src/refererDetection.js';
Expand Down Expand Up @@ -219,51 +218,53 @@ export const spec = {

if (body && body.slots && isArray(body.slots)) {
body.slots.forEach(slot => {
const bidRequest = find(request.bidRequests, b => b.adUnitCode === slot.impid && (!b.params.zoneId || parseInt(b.params.zoneId) === slot.zoneid));
const bidId = bidRequest.bidId;
const bid = {
requestId: bidId,
cpm: slot.cpm,
currency: slot.currency,
netRevenue: true,
ttl: slot.ttl || 60,
creativeId: slot.creativecode,
width: slot.width,
height: slot.height,
dealId: slot.deal,
};
if (body.ext?.paf?.transmission && slot.ext?.paf?.content_id) {
const pafResponseMeta = {
content_id: slot.ext.paf.content_id,
transmission: response.ext.paf.transmission
const bidRequest = getAssociatedBidRequest(request.bidRequests, slot);
if (bidRequest) {
const bidId = bidRequest.bidId;
const bid = {
requestId: bidId,
cpm: slot.cpm,
currency: slot.currency,
netRevenue: true,
ttl: slot.ttl || 60,
creativeId: slot.creativecode,
width: slot.width,
height: slot.height,
dealId: slot.deal,
};
bid.meta = Object.assign({}, bid.meta, { paf: pafResponseMeta });
}
if (slot.adomain) {
bid.meta = Object.assign({}, bid.meta, { advertiserDomains: [slot.adomain].flat() });
}
if (slot.ext?.meta?.networkName) {
bid.meta = Object.assign({}, bid.meta, { networkName: slot.ext.meta.networkName })
}
if (slot.native) {
if (bidRequest.params.nativeCallback) {
bid.ad = createNativeAd(bidId, slot.native, bidRequest.params.nativeCallback);
} else {
bid.native = createPrebidNativeAd(slot.native);
bid.mediaType = NATIVE;
if (body.ext?.paf?.transmission && slot.ext?.paf?.content_id) {
const pafResponseMeta = {
content_id: slot.ext.paf.content_id,
transmission: response.ext.paf.transmission
};
bid.meta = Object.assign({}, bid.meta, { paf: pafResponseMeta });
}
} else if (slot.video) {
bid.vastUrl = slot.displayurl;
bid.mediaType = VIDEO;
const context = deepAccess(bidRequest, 'mediaTypes.video.context');
// if outstream video, add a default render for it.
if (context === OUTSTREAM) {
bid.renderer = createOutstreamVideoRenderer(slot);
if (slot.adomain) {
bid.meta = Object.assign({}, bid.meta, { advertiserDomains: [slot.adomain].flat() });
}
} else {
bid.ad = slot.creative;
if (slot.ext?.meta?.networkName) {
bid.meta = Object.assign({}, bid.meta, { networkName: slot.ext.meta.networkName })
}
if (slot.native) {
if (bidRequest.params.nativeCallback) {
bid.ad = createNativeAd(bidId, slot.native, bidRequest.params.nativeCallback);
} else {
bid.native = createPrebidNativeAd(slot.native);
bid.mediaType = NATIVE;
}
} else if (slot.video) {
bid.vastUrl = slot.displayurl;
bid.mediaType = VIDEO;
const context = deepAccess(bidRequest, 'mediaTypes.video.context');
// if outstream video, add a default render for it.
if (context === OUTSTREAM) {
bid.renderer = createOutstreamVideoRenderer(slot);
}
} else {
bid.ad = slot.creative;
}
bids.push(bid);
}
bids.push(bid);
});
}

Expand Down Expand Up @@ -786,6 +787,27 @@ function createOutstreamVideoRenderer(slot) {
return renderer;
}

function getAssociatedBidRequest(bidRequests, slot) {
for (const request of bidRequests) {
if (request.adUnitCode === slot.impid) {
if (request.params.zoneId && parseInt(request.params.zoneId) === slot.zoneid) {
return request;
} else if (slot.native) {
if (request.mediaTypes?.native || request.nativeParams) {
return request;
}
} else if (slot.video) {
if (request.mediaTypes?.video) {
return request;
}
} else if (request.mediaTypes?.banner || request.sizes) {
return request;
}
}
}
return undefined;
}

export function tryGetCriteoFastBid() {
// begin ref#1
try {
Expand Down
201 changes: 201 additions & 0 deletions test/spec/modules/criteoBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,11 @@ describe('The Criteo bidding adapter', function () {
bidRequests: [{
adUnitCode: 'test-requestId',
bidId: 'test-bidId',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
params: {
networkId: 456,
}
Expand All @@ -1904,6 +1909,202 @@ describe('The Criteo bidding adapter', function () {
expect(bids[0].meta.networkName).to.equal('Criteo');
});

it('should properly parse a bid response with a networkId with twin ad unit banner win', function () {
const response = {
body: {
slots: [{
impid: 'test-requestId',
cpm: 1.23,
creative: 'test-ad',
creativecode: 'test-crId',
width: 728,
height: 90,
deal: 'myDealCode',
adomain: ['criteo.com'],
ext: {
meta: {
networkName: 'Criteo'
}
}
}],
},
};
const request = {
bidRequests: [{
adUnitCode: 'test-requestId',
bidId: 'test-bidId',
mediaTypes: {
video: {
context: 'instream',
mimes: ['video/mpeg'],
playerSize: [640, 480],
protocols: [5, 6],
maxduration: 30,
api: [1, 2]
}
},
params: {
networkId: 456,
},
}, {
adUnitCode: 'test-requestId',
bidId: 'test-bidId2',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
params: {
networkId: 456,
}
}]
};
const bids = spec.interpretResponse(response, request);
expect(bids).to.have.lengthOf(1);
expect(bids[0].requestId).to.equal('test-bidId2');
expect(bids[0].cpm).to.equal(1.23);
expect(bids[0].ad).to.equal('test-ad');
expect(bids[0].creativeId).to.equal('test-crId');
expect(bids[0].width).to.equal(728);
expect(bids[0].height).to.equal(90);
expect(bids[0].dealId).to.equal('myDealCode');
expect(bids[0].meta.advertiserDomains[0]).to.equal('criteo.com');
expect(bids[0].meta.networkName).to.equal('Criteo');
});

it('should properly parse a bid response with a networkId with twin ad unit video win', function () {
const response = {
body: {
slots: [{
impid: 'test-requestId',
bidId: 'abc123',
cpm: 1.23,
displayurl: 'http://test-ad',
width: 728,
height: 90,
zoneid: 123,
video: true,
ext: {
meta: {
networkName: 'Criteo'
}
}
}],
},
};
const request = {
bidRequests: [{
adUnitCode: 'test-requestId',
bidId: 'test-bidId',
mediaTypes: {
video: {
context: 'instream',
mimes: ['video/mpeg'],
playerSize: [728, 90],
protocols: [5, 6],
maxduration: 30,
api: [1, 2]
}
},
params: {
networkId: 456,
},
}, {
adUnitCode: 'test-requestId',
bidId: 'test-bidId2',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
params: {
networkId: 456,
}
}]
};
const bids = spec.interpretResponse(response, request);
expect(bids).to.have.lengthOf(1);
expect(bids[0].requestId).to.equal('test-bidId');
expect(bids[0].cpm).to.equal(1.23);
expect(bids[0].vastUrl).to.equal('http://test-ad');
expect(bids[0].mediaType).to.equal(VIDEO);
});

it('should properly parse a bid response with a networkId with twin ad unit native win', function () {
const response = {
body: {
slots: [{
impid: 'test-requestId',
cpm: 1.23,
creative: 'test-ad',
creativecode: 'test-crId',
width: 728,
height: 90,
deal: 'myDealCode',
adomain: ['criteo.com'],
native: {
'products': [{
'sendTargetingKeys': false,
'title': 'Product title',
'description': 'Product desc',
'price': '100',
'click_url': 'https://product.click',
'image': {
'url': 'https://publisherdirect.criteo.com/publishertag/preprodtest/creative.png',
'height': 300,
'width': 300
},
'call_to_action': 'Try it now!'
}],
'advertiser': {
'description': 'sponsor',
'domain': 'criteo.com',
'logo': { 'url': 'https://www.criteo.com/images/criteo-logo.svg', 'height': 300, 'width': 300 }
},
'privacy': {
'optout_click_url': 'https://info.criteo.com/privacy/informations',
'optout_image_url': 'https://static.criteo.net/flash/icon/nai_small.png',
},
'impression_pixels': [{ 'url': 'https://my-impression-pixel/test/impression' }, { 'url': 'https://cas.com/lg.com' }]
},
ext: {
meta: {
networkName: 'Criteo'
}
}
}],
},
};
const request = {
bidRequests: [{
adUnitCode: 'test-requestId',
bidId: 'test-bidId',
mediaTypes: {
native: {}
},
params: {
networkId: 456,
},
}, {
adUnitCode: 'test-requestId',
bidId: 'test-bidId2',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
params: {
networkId: 456,
}
}]
};
const bids = spec.interpretResponse(response, request);
expect(bids).to.have.lengthOf(1);
expect(bids[0].requestId).to.equal('test-bidId');
expect(bids[0].cpm).to.equal(1.23);
expect(bids[0].mediaType).to.equal(NATIVE);
});

it('should properly parse a bid response with a zoneId', function () {
const response = {
body: {
Expand Down

0 comments on commit 5249b47

Please sign in to comment.