Skip to content

Commit

Permalink
Make response headers available to the specs (prebid#1748)
Browse files Browse the repository at this point in the history
* Updated the bidderFactory to make headers accessible to the spec files.

* Updated the platform.io adapter to handle the new format.

* Updated the jcm adapter.
  • Loading branch information
dbemiller authored and mattpr committed Oct 31, 2017
1 parent c2e0794 commit 751ccf1
Show file tree
Hide file tree
Showing 16 changed files with 75 additions and 39 deletions.
1 change: 1 addition & 0 deletions modules/adbutlerBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export const spec = {
var width;
var height;

serverResponse = serverResponse.body;
if (serverResponse && serverResponse.status === 'SUCCESS' && bidObj) {
CPM = serverResponse.cpm;
minCPM = utils.getBidIdParameter('minCPM', bidObj.params);
Expand Down
1 change: 1 addition & 0 deletions modules/appnexusAstBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const spec = {
* @return {Bid[]} An array of bids which were nested inside the server.
*/
interpretResponse: function(serverResponse, {bidderRequest}) {
serverResponse = serverResponse.body;
const bids = [];
if (!serverResponse || serverResponse.error) {
let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`;
Expand Down
1 change: 1 addition & 0 deletions modules/beachfrontBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const spec = {
},

interpretResponse(response, { bidRequest }) {
response = response.body;
if (!response || !response.url || !response.bidPrice) {
utils.logWarn(`No valid bids from ${spec.code} bidder`);
return [];
Expand Down
1 change: 1 addition & 0 deletions modules/jcmBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const spec = {

interpretResponse: function(serverResponse) {
const bidResponses = [];
serverResponse = serverResponse.body;
// loop through serverResponses
if (serverResponse) {
if (serverResponse.bids) {
Expand Down
2 changes: 1 addition & 1 deletion modules/platformioBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const spec = {
};
},
interpretResponse: (response, request) => (
bidResponseAvailable(request, response)
bidResponseAvailable(request, response.body)
),
};
function bidResponseAvailable(bidRequest, bidResponse) {
Expand Down
1 change: 1 addition & 0 deletions modules/pulsepointLiteBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const spec = {
function bidResponseAvailable(bidRequest, bidResponse) {
const idToImpMap = {};
const idToBidMap = {};
bidResponse = bidResponse.body
// extract the request bids and the response bids, keyed by impr-id
const ortbRequest = parse(bidRequest.data);
ortbRequest.imp.forEach(imp => {
Expand Down
1 change: 1 addition & 0 deletions modules/rubiconBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export const spec = {
* @return {Bid[]} An array of bids which
*/
interpretResponse: function(responseObj, {bidRequest}) {
responseObj = responseObj.body
let ads = responseObj.ads;

// check overall response
Expand Down
25 changes: 23 additions & 2 deletions src/adapters/bidderFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { logWarn, logError, parseQueryStringParameters, delayExecution } from 's
* @property {function(BidRequest[], bidderRequest): ServerRequest|ServerRequest[]} buildRequests Build the request to the Server
* which requests Bids for the given array of Requests. Each BidRequest in the argument array is guaranteed to have
* passed the isBidRequestValid() test.
* @property {function(*, BidRequest): Bid[]} interpretResponse Given a successful response from the Server,
* @property {function(ServerResponse, BidRequest): Bid[]} interpretResponse Given a successful response from the Server,
* interpret it and return the Bid objects. This function will be run inside a try/catch.
* If it throws any errors, your bids will be discarded.
* @property {function(SyncOptions, Array): UserSync[]} [getUserSyncs] Given an array of all the responses
Expand Down Expand Up @@ -72,6 +72,15 @@ import { logWarn, logError, parseQueryStringParameters, delayExecution } from 's
* JSON-serialized into the Request body.
*/

/**
* @typedef {object} ServerResponse
*
* @property {*} body The response body. If this is legal JSON, then it will be parsed. Otherwise it'll be a
* string with the body's content.
* @property {{get: function(string): string} headers The response headers.
* Call this like `ServerResponse.headers.get("Content-Type")`
*/

/**
* @typedef {object} Bid
*
Expand Down Expand Up @@ -263,10 +272,16 @@ export function newBidder(spec) {
// If the server responds successfully, use the adapter code to unpack the Bids from it.
// If the adapter code fails, no bids should be added. After all the bids have been added, make
// sure to call the `onResponse` function so that we're one step closer to calling fillNoBids().
function onSuccess(response) {
function onSuccess(response, responseObj) {
try {
response = JSON.parse(response);
} catch (e) { /* response might not be JSON... that's ok. */ }

// Make response headers available for #1742. These are lazy-loaded because most adapters won't need them.
response = {
body: response,
headers: headerParser(responseObj)
};
responses.push(response);

let bids;
Expand Down Expand Up @@ -296,6 +311,12 @@ export function newBidder(spec) {
logWarn(`Bidder ${spec.code} made bid for unknown request ID: ${bid.requestId}. Ignoring.`);
}
}

function headerParser(xmlHttpResponse) {
return {
get: responseObj.getResponseHeader.bind(responseObj)
};
}
}

// If the server responds with an error, there's not much we can do. Log it, and make sure to
Expand Down
24 changes: 13 additions & 11 deletions test/spec/modules/adbutlerBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,19 @@ describe('AdButler adapter', () => {
describe('bid responses', () => {
it('should return complete bid response', () => {
let serverResponse = {
status: 'SUCCESS',
account_id: 167283,
zone_id: 210093,
cpm: 1.5,
width: 300,
height: 250,
place: 0,
ad_code: '<img src="http://image.source.com/img" alt="" title="" border="0" width="300" height="250">',
tracking_pixels: [
'http://tracking.pixel.com/params=info'
]
body: {
status: 'SUCCESS',
account_id: 167283,
zone_id: 210093,
cpm: 1.5,
width: 300,
height: 250,
place: 0,
ad_code: '<img src="http://image.source.com/img" alt="" title="" border="0" width="300" height="250">',
tracking_pixels: [
'http://tracking.pixel.com/params=info'
]
}
},
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]});

Expand Down
8 changes: 4 additions & 4 deletions test/spec/modules/appnexusAstBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ describe('AppNexusAdapter', () => {
];
let bidderRequest;

let result = spec.interpretResponse(response, {bidderRequest});
let result = spec.interpretResponse({ body: response }, {bidderRequest});
expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0]));
});

Expand All @@ -322,7 +322,7 @@ describe('AppNexusAdapter', () => {
};
let bidderRequest;

let result = spec.interpretResponse(response, {bidderRequest});
let result = spec.interpretResponse({ body: response }, {bidderRequest});
expect(result.length).to.equal(0);
});

Expand All @@ -343,7 +343,7 @@ describe('AppNexusAdapter', () => {
};
let bidderRequest;

let result = spec.interpretResponse(response, {bidderRequest});
let result = spec.interpretResponse({ body: response }, {bidderRequest});
expect(result[0]).to.have.property('vastUrl');
expect(result[0]).to.have.property('descriptionUrl');
expect(result[0]).to.have.property('mediaType', 'video');
Expand Down Expand Up @@ -376,7 +376,7 @@ describe('AppNexusAdapter', () => {
};
let bidderRequest;

let result = spec.interpretResponse(response1, {bidderRequest});
let result = spec.interpretResponse({ body: response1 }, {bidderRequest});
expect(result[0].native.title).to.equal('Native Creative');
expect(result[0].native.body).to.equal('Cool description great stuff');
expect(result[0].native.cta).to.equal('Do it');
Expand Down
8 changes: 4 additions & 4 deletions test/spec/modules/beachfrontBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,23 @@ describe('BeachfrontAdapter', () => {

describe('spec.interpretResponse', () => {
it('should return no bids if the response is not valid', () => {
const bidResponse = spec.interpretResponse(null, { bidRequest });
const bidResponse = spec.interpretResponse({ body: null }, { bidRequest });
expect(bidResponse.length).to.equal(0);
});

it('should return no bids if the response "url" is missing', () => {
const serverResponse = {
bidPrice: 5.00
};
const bidResponse = spec.interpretResponse(serverResponse, { bidRequest });
const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
expect(bidResponse.length).to.equal(0);
});

it('should return no bids if the response "bidPrice" is missing', () => {
const serverResponse = {
url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da'
};
const bidResponse = spec.interpretResponse(serverResponse, { bidRequest });
const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
expect(bidResponse.length).to.equal(0);
});

Expand All @@ -130,7 +130,7 @@ describe('BeachfrontAdapter', () => {
url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da',
cmpId: '123abc'
};
const bidResponse = spec.interpretResponse(serverResponse, { bidRequest });
const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
expect(bidResponse).to.deep.equal({
requestId: bidRequest.bidId,
bidderCode: spec.code,
Expand Down
4 changes: 2 additions & 2 deletions test/spec/modules/jcmBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ describe('jcmAdapter', () => {
}
];

let result = spec.interpretResponse(serverResponse);
let result = spec.interpretResponse({ body: serverResponse });
expect(Object.keys(result[0]).length).to.equal(Object.keys(expectedResponse[0]).length);
expect(Object.keys(result[0]).requestId).to.equal(Object.keys(expectedResponse[0]).requestId);
expect(Object.keys(result[0]).bidderCode).to.equal(Object.keys(expectedResponse[0]).bidderCode);
Expand All @@ -112,7 +112,7 @@ describe('jcmAdapter', () => {
it('handles nobid responses', () => {
let serverResponse = {'bids': []};

let result = spec.interpretResponse(serverResponse);
let result = spec.interpretResponse({ body: serverResponse });
expect(result.length).to.equal(0);
});
});
Expand Down
4 changes: 2 additions & 2 deletions test/spec/modules/platformioBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('Platformio Adapter Tests', () => {
}]
}]
};
const bids = spec.interpretResponse(ortbResponse, request);
const bids = spec.interpretResponse({ body: ortbResponse }, request);
expect(bids).to.have.lengthOf(1);
// verify first bid
const bid = bids[0];
Expand All @@ -78,7 +78,7 @@ describe('Platformio Adapter Tests', () => {

it('Verify full passback', () => {
const request = spec.buildRequests(slotConfigs);
const bids = spec.interpretResponse(null, request)
const bids = spec.interpretResponse({ body: null }, request)
expect(bids).to.have.lengthOf(0);
});

Expand Down
6 changes: 3 additions & 3 deletions test/spec/modules/pulsepointLiteBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ describe('PulsePoint Lite Adapter Tests', () => {
}]
}]
};
const bids = spec.interpretResponse(ortbResponse, request);
const bids = spec.interpretResponse({ body: ortbResponse }, request);
expect(bids).to.have.lengthOf(1);
// verify first bid
const bid = bids[0];
Expand All @@ -104,7 +104,7 @@ describe('PulsePoint Lite Adapter Tests', () => {

it('Verify full passback', () => {
const request = spec.buildRequests(slotConfigs);
const bids = spec.interpretResponse(null, request)
const bids = spec.interpretResponse({ body: null }, request)
expect(bids).to.have.lengthOf(0);
});

Expand Down Expand Up @@ -171,7 +171,7 @@ describe('PulsePoint Lite Adapter Tests', () => {
}]
}]
};
const bids = spec.interpretResponse(ortbResponse, request);
const bids = spec.interpretResponse({ body: ortbResponse }, request);
// verify bid
const bid = bids[0];
expect(bid.cpm).to.equal(1.25);
Expand Down
12 changes: 6 additions & 6 deletions test/spec/modules/rubiconBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ describe('the rubicon adapter', () => {
]
};

let bids = spec.interpretResponse(response, {
let bids = spec.interpretResponse({ body: response }, {
bidRequest: bidderRequest.bids[0]
});

Expand Down Expand Up @@ -654,7 +654,7 @@ describe('the rubicon adapter', () => {
}]
};

let bids = spec.interpretResponse(response, {
let bids = spec.interpretResponse({ body: response }, {
bidRequest: bidderRequest.bids[0]
});

Expand All @@ -677,7 +677,7 @@ describe('the rubicon adapter', () => {
'ads': []
};

let bids = spec.interpretResponse(response, {
let bids = spec.interpretResponse({ body: response }, {
bidRequest: bidderRequest.bids[0]
});

Expand All @@ -701,7 +701,7 @@ describe('the rubicon adapter', () => {
}]
};

let bids = spec.interpretResponse(response, {
let bids = spec.interpretResponse({ body: response }, {
bidRequest: bidderRequest.bids[0]
});

Expand All @@ -711,7 +711,7 @@ describe('the rubicon adapter', () => {
it('should handle an error because of malformed json response', () => {
let response = '{test{';

let bids = spec.interpretResponse(response, {
let bids = spec.interpretResponse({ body: response }, {
bidRequest: bidderRequest.bids[0]
});

Expand Down Expand Up @@ -752,7 +752,7 @@ describe('the rubicon adapter', () => {
'account_id': 7780
};

let bids = spec.interpretResponse(response, {
let bids = spec.interpretResponse({ body: response }, {
bidRequest: bidderRequest.bids[0]
});

Expand Down
15 changes: 11 additions & 4 deletions test/spec/unit/core/bidderFactory_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ describe('bidders created by newBidder', () => {

beforeEach(() => {
ajaxStub = sinon.stub(ajax, 'ajax', function(url, callbacks) {
callbacks.success('response body');
const fakeResponse = sinon.stub();
fakeResponse.returns('headerContent');
callbacks.success('response body', { getResponseHeader: fakeResponse });
});
userSyncStub = sinon.stub(userSync, 'registerSync')
});
Expand All @@ -275,7 +277,7 @@ describe('bidders created by newBidder', () => {
userSyncStub.restore();
});

it('should call spec.interpretResponse() with the response body content', () => {
it('should call spec.interpretResponse() with the response content', () => {
const bidder = newBidder(spec);

spec.isBidRequestValid.returns(true);
Expand All @@ -289,7 +291,9 @@ describe('bidders created by newBidder', () => {
bidder.callBids(MOCK_BIDS_REQUEST);

expect(spec.interpretResponse.calledOnce).to.equal(true);
expect(spec.interpretResponse.firstCall.args[0]).to.equal('response body');
const response = spec.interpretResponse.firstCall.args[0]
expect(response.body).to.equal('response body')
expect(response.headers.get('some-header')).to.equal('headerContent');
expect(spec.interpretResponse.firstCall.args[1]).to.deep.equal({
method: 'POST',
url: 'test.url.com',
Expand Down Expand Up @@ -364,7 +368,10 @@ describe('bidders created by newBidder', () => {
bidder.callBids(MOCK_BIDS_REQUEST);

expect(spec.getUserSyncs.calledOnce).to.equal(true);
expect(spec.getUserSyncs.firstCall.args[1]).to.deep.equal(['response body']);
expect(spec.getUserSyncs.firstCall.args[1].length).to.equal(1);
expect(spec.getUserSyncs.firstCall.args[1][0].body).to.equal('response body');
expect(spec.getUserSyncs.firstCall.args[1][0].headers).to.have.property('get');
expect(spec.getUserSyncs.firstCall.args[1][0].headers.get).to.be.a('function');
});

it('should register usersync pixels', () => {
Expand Down

0 comments on commit 751ccf1

Please sign in to comment.