Skip to content

Commit

Permalink
Sortable adapter: support different floors for each size (#2868)
Browse files Browse the repository at this point in the history
And some other minor fixes
- Update the way keywords are send to the server
- Use the correct creativeId
  • Loading branch information
Bryan Gahagan authored and idettman committed Jul 30, 2018
1 parent f21c683 commit 3e3ba81
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 9 deletions.
22 changes: 18 additions & 4 deletions modules/sortableBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,19 @@ export const spec = {
isBidRequestValid: function(bid) {
const sortableConfig = config.getConfig('sortable');
const haveSiteId = (sortableConfig && !!sortableConfig.siteId) || bid.params.siteId;
return !!(bid.params.tagId && haveSiteId && bid.sizes &&
const validFloor = !bid.params.floor || utils.isNumber(bid.params.floor);
const validSize = /\d+x\d+/;
const validFloorSizeMap = !bid.params.floorSizeMap ||
(utils.isPlainObject(bid.params.floorSizeMap) &&
Object.keys(bid.params.floorSizeMap).every(size =>
size.match(validSize) && utils.isNumber(bid.params.floorSizeMap[size])
))
const validKeywords = !bid.params.keywords ||
(utils.isPlainObject(bid.params.keywords) &&
Object.keys(bid.params.keywords).every(key =>
utils.isStr(key) && utils.isStr(bid.params.keywords[key])
))
return !!(bid.params.tagId && haveSiteId && validFloor && validFloorSizeMap && validKeywords && bid.sizes &&
bid.sizes.every(sizeArr => sizeArr.length == 2 && sizeArr.every(num => utils.isNumber(num))));
},

Expand All @@ -36,14 +48,16 @@ export const spec = {
rv.bidfloor = bid.params.floor;
}
if (bid.params.keywords) {
let keywords = utils._map(bid.params.keywords, (foo, bar) => ({name: bar, value: foo}));
rv.ext.keywords = keywords;
rv.ext.keywords = bid.params.keywords;
}
if (bid.params.bidderParams) {
utils._each(bid.params.bidderParams, (params, partner) => {
rv.ext[partner] = params;
});
}
if (bid.params.floorSizeMap) {
rv.ext.floorSizeMap = bid.params.floorSizeMap;
}
return rv;
});
const gdprConsent = bidderRequest && bidderRequest.gdprConsent;
Expand Down Expand Up @@ -95,7 +109,7 @@ export const spec = {
cpm: parseFloat(bid.price),
width: parseInt(bid.w),
height: parseInt(bid.h),
creativeId: bid.id,
creativeId: bid.crid || bid.id,
dealId: bid.dealid || null,
currency: 'USD',
netRevenue: true,
Expand Down
75 changes: 70 additions & 5 deletions test/spec/modules/sortableBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ describe('sortableBidAdapter', function() {
'keywords': {
'key1': 'val1',
'key2': 'val2'
},
'floorSizeMap': {
'728x90': 0.15,
'300x250': 1.20
}
},
'adUnitCode': 'adunit-code',
Expand Down Expand Up @@ -58,6 +62,45 @@ describe('sortableBidAdapter', function() {
bid.params = {};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});

it('should return false when the floorSizeMap is invalid', () => {
let bid = makeBid();
bid.params.floorSizeMap = {
'sixforty by foureighty': 1234
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
bid.params.floorSizeMap = {
'728x90': 'three'
}
expect(spec.isBidRequestValid(bid)).to.equal(false);
bid.params.floorSizeMap = 'a';
expect(spec.isBidRequestValid(bid)).to.equal(false);
});

it('should return true when the floorSizeMap is missing or empty', () => {
let bid = makeBid();
bid.params.floorSizeMap = {};
expect(spec.isBidRequestValid(bid)).to.equal(true);
delete bid.params.floorSizeMap;
expect(spec.isBidRequestValid(bid)).to.equal(true);
});
it('should return false when the keywords are invalid', () => {
let bid = makeBid();
bid.params.keywords = {
'badval': 1234
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
bid.params.keywords = 'a';
expect(spec.isBidRequestValid(bid)).to.equal(false);
});

it('should return true when the keywords are missing or empty', () => {
let bid = makeBid();
bid.params.keywords = {};
expect(spec.isBidRequestValid(bid)).to.equal(true);
delete bid.params.keywords;
expect(spec.isBidRequestValid(bid)).to.equal(true);
});
});

describe('buildRequests', () => {
Expand All @@ -70,6 +113,10 @@ describe('sortableBidAdapter', function() {
'keywords': {
'key1': 'val1',
'key2': 'val2'
},
'floorSizeMap': {
'728x90': 0.15,
'300x250': 1.20
}
},
'sizes': [
Expand Down Expand Up @@ -102,14 +149,21 @@ describe('sortableBidAdapter', function() {
});

it('includes the params in the bid request', () => {
expect(requestBody.imp[0].ext.keywords).to.deep.equal([
{'name': 'key1', 'value': 'val1'},
{'name': 'key2', 'value': 'val2'}
]);
expect(requestBody.imp[0].ext.keywords).to.deep.equal(
{'key1': 'val1',
'key2': 'val2'}
);
expect(requestBody.site.publisher.id).to.equal('example.com');
expect(requestBody.imp[0].tagid).to.equal('403370');
expect(requestBody.imp[0].bidfloor).to.equal(0.21);
});

it('should have the floor size map set', () => {
expect(requestBody.imp[0].ext.floorSizeMap).to.deep.equal({
'728x90': 0.15,
'300x250': 1.20
});
});
});

describe('interpretResponse', () => {
Expand All @@ -122,6 +176,7 @@ describe('sortableBidAdapter', function() {
'bid': [
{
'id': '6vmb3isptf',
'crid': 'sortablescreative',
'impid': '322add653672f68',
'price': 1.22,
'adm': '<!-- creative -->',
Expand All @@ -144,7 +199,7 @@ describe('sortableBidAdapter', function() {
'cpm': 1.22,
'width': 728,
'height': 90,
'creativeId': '6vmb3isptf',
'creativeId': 'sortablescreative',
'dealId': null,
'currency': 'USD',
'netRevenue': true,
Expand All @@ -159,6 +214,16 @@ describe('sortableBidAdapter', function() {
expect(result[0]).to.deep.equal(expectedBid);
});

it('should handle a missing crid', () => {
let noCridResponse = makeResponse();
delete noCridResponse.body.seatbid[0].bid[0].crid;
const fallbackCrid = noCridResponse.body.seatbid[0].bid[0].id;
let noCridResult = Object.assign({}, expectedBid, {'creativeId': fallbackCrid});
let result = spec.interpretResponse(noCridResponse);
expect(result.length).to.equal(1);
expect(result[0]).to.deep.equal(noCridResult);
});

it('should handle a missing nurl', () => {
let noNurlResponse = makeResponse();
delete noNurlResponse.body.seatbid[0].bid[0].nurl;
Expand Down

0 comments on commit 3e3ba81

Please sign in to comment.