Skip to content

Commit

Permalink
Add native support
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugo Duthil committed Feb 15, 2017
1 parent 4ae8023 commit 2a1c1be
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 18 deletions.
65 changes: 49 additions & 16 deletions src/adapters/criteo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var bidfactory = require('../bidfactory.js');
var bidmanager = require('../bidmanager.js');
var adloader = require('../adloader');
var utils = require('../utils')

var CriteoAdapter = function CriteoAdapter() {

Expand Down Expand Up @@ -34,11 +35,8 @@ var CriteoAdapter = function CriteoAdapter() {

// generate the bidding event
var biddingEventFunc = function () {

var bids = params.bids || [];

var slots = [];

var isAudit = false;

// build slots before sending one multi-slots bid request
Expand All @@ -47,7 +45,8 @@ var CriteoAdapter = function CriteoAdapter() {
slots.push(
new Criteo.PubTag.DirectBidding.DirectBiddingSlot(
bid.placementCode,
bid.params.zoneId
bid.params.zoneId,
bid.params.nativeCallback ? bid.params.nativeCallback : undefined
)
);

Expand Down Expand Up @@ -103,18 +102,8 @@ var CriteoAdapter = function CriteoAdapter() {
}

// register the bid response
var bidObject;
if (bidResponse) {
bidObject = bidfactory.createBid(1);
bidObject.bidderCode = _bidderCode;
bidObject.cpm = bidResponse.cpm;
bidObject.ad = bidResponse.creative;
bidObject.width = bidResponse.width;
bidObject.height = bidResponse.height;
}
else {
bidObject = _invalidBidResponse();
}
let bidObject = _buildBidObject(bidResponse, slots[i]);

bidmanager.addBidResponse(slots[i].impId, bidObject);
}
};
Expand All @@ -134,6 +123,50 @@ var CriteoAdapter = function CriteoAdapter() {
return bidObject;
}

function _buildBidObject(bidResponse, slot) {
let bidObject;
if (bidResponse) {

// map the common fields
bidObject = bidfactory.createBid(1);
bidObject.bidderCode = _bidderCode;
bidObject.cpm = bidResponse.cpm;

// in case of native
if (slot.nativeCallback && bidResponse.native) {

if (typeof slot.nativeCallback !== "function") {
utils.logError("Criteo bid: nativeCallback parameter is not a function");
} else {

// store the callbacks in a global object
window.criteo_pubtag.native_slots = window.criteo_pubtag.native_slots || {};
window.criteo_pubtag.native_slots[""+bidObject.adId] = { callback: slot.nativeCallback, nativeResponse: bidResponse.native };

// this code is executed in an iframe, we need to get a reference to the
// publishertag in the main window to retrieve native responses and callbacks.
// it doesn't work with safeframes
bidObject.ad = "<script type=\"text/javascript\">";
bidObject.ad += "let win = window; for (let i=0; i<10; ++i) { win = win.parent; if (win.criteo_pubtag && win.criteo_pubtag.native_slots) {";
bidObject.ad += "let responseSlot = win.criteo_pubtag.native_slots[\"" + bidObject.adId + "\"];";
bidObject.ad += "responseSlot.callback(responseSlot.nativeResponse);break;";
bidObject.ad += "}}</script>";
}
} else {
// width and height are only relevant with non-native requests.
// native requests will always return a 2x2 zone size.
bidObject.width = bidResponse.width;
bidObject.height = bidResponse.height;
bidObject.ad = bidResponse.creative;
}

}
else {
bidObject = _invalidBidResponse();
}
return bidObject;
}

return {
callBids: _callBids
};
Expand Down
46 changes: 44 additions & 2 deletions test/spec/adapters/criteo_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,25 @@ describe('criteo adapter test', () => {
}
}
]
};
};


let validNativeResponse = {slots: [{impid: "foo", cpm: 1.12, native: {productName: "product0"}}]};
let validNativeBid = {
bidderCode: 'criteo',
bids: [
{
bidder: 'criteo',
placementCode: 'foo',
sizes: [[250, 350]],
params: {
zoneId: 32934,
audit: 'true',
nativeCallback: function(nativeJson) {console.log("Product name: " + nativeJson.productName)}
}
}
]
}

beforeEach(() => {
adapter = new Adapter();
Expand All @@ -61,7 +79,7 @@ describe('criteo adapter test', () => {
stubAddBidResponse.restore();
});

describe('adding bids to the manager', () => {
describe('adding bids to the manager with non-native bids', () => {
let server;

beforeEach(() => {
Expand Down Expand Up @@ -114,6 +132,30 @@ describe('adding bids to the manager', () => {
});
adapter.callBids(validBid);
});
});

describe('adding bids to the manager with native bids', () => {
let server;

beforeEach(() => {
server = sinon.fakeServer.create({autoRespond: true, respondImmediately: true});
server.respondWith(JSON.stringify(validNativeResponse));
});

it('adds creative to the response of a native valid request', (done) => {
stubAddBidResponse = sinon.stub(bidManager, 'addBidResponse', function (adUnitCode, bid) {

let expectedAdProperty = "<script type=\"text/javascript\">";
expectedAdProperty += "let win = window; for (let i=0; i<10; ++i) { win = win.parent; if (win.criteo_pubtag && win.criteo_pubtag.native_slots) {";
expectedAdProperty += "let responseSlot = win.criteo_pubtag.native_slots[\"" + bid.adId + "\"];";
expectedAdProperty += "responseSlot.callback(responseSlot.nativeResponse);break;";
expectedAdProperty += "}}</script>";

expect(bid).to.have.property('ad', expectedAdProperty);
done();
});
adapter.callBids(validNativeBid);
});
});

describe('dealing with unexpected situations', () => {
Expand Down

0 comments on commit 2a1c1be

Please sign in to comment.