Skip to content

Commit

Permalink
OpenX Adapter: Placement Id Support (prebid#2774)
Browse files Browse the repository at this point in the history
* chore: update adapter version number

* feat: Added support for placementId as a replacement to ad unit id.
  • Loading branch information
jimee02 authored and dluxemburg committed Jul 17, 2018
1 parent ef9ae07 commit f288c98
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 40 deletions.
31 changes: 22 additions & 9 deletions modules/openxBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {parse} from 'src/url';
const SUPPORTED_AD_TYPES = [BANNER, VIDEO];
const BIDDER_CODE = 'openx';
const BIDDER_CONFIG = 'hb_pb';
const BIDDER_VERSION = '2.1.1';
const BIDDER_VERSION = '2.1.2';

let shouldSendBoPixel = true;

export function resetBoPixel() {
shouldSendBoPixel = true;
}
Expand All @@ -19,6 +20,10 @@ export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: SUPPORTED_AD_TYPES,
isBidRequestValid: function (bidRequest) {
if (bidRequest.mediaTypes && bidRequest.mediaTypes.banner) {
return !!((bidRequest.params.unit || bidRequest.params.placementId) && bidRequest.params.delDomain);
}

return !!(bidRequest.params.unit && bidRequest.params.delDomain);
},
buildRequests: function (bidRequests, bidderRequest) {
Expand Down Expand Up @@ -48,14 +53,14 @@ export const spec = {
return mediaType === VIDEO ? createVideoBidResponses(oxResponseObj, serverRequest.payload)
: createBannerBidResponses(oxResponseObj, serverRequest.payload);
},
getUserSyncs: function(syncOptions, responses) {
getUserSyncs: function (syncOptions, responses) {
if (syncOptions.iframeEnabled) {
let url = utils.deepAccess(responses, '0.body.ads.pixels') ||
utils.deepAccess(responses, '0.body.pixels') ||
'//u.openx.net/w/1.0/pd';
utils.deepAccess(responses, '0.body.pixels') ||
'//u.openx.net/w/1.0/pd';
return [{
type: 'iframe',
url: url,
url: url
}];
}
}
Expand Down Expand Up @@ -214,14 +219,22 @@ function buildCommonQueryParamsFromBids(bids, bidderRequest) {
}

function buildOXBannerRequest(bids, bidderRequest) {
let customParamsForAllBids = [];
let hasCustomParam = false;
let queryParams = buildCommonQueryParamsFromBids(bids, bidderRequest);

queryParams.auid = utils._map(bids, bid => bid.params.unit).join(',');
let auids = utils._map(bids, bid => bid.params.unit);
let pids = utils._map(bids, bid => bid.params.placementId);
queryParams.aus = utils._map(bids, bid => utils.parseSizesInput(bid.sizes).join(',')).join('|');
queryParams.bc = bids[0].params.bc || `${BIDDER_CONFIG}_${BIDDER_VERSION}`;
queryParams.divs = utils._map(bids, bid => bid.adUnitCode).join(',');

if (auids.some(auid => auid)) {
queryParams.auid = auids.join(',');
}
if (pids.some(pid => pid)) {
queryParams.pids = pids.join(',');
}

let customParamsForAllBids = [];
let hasCustomParam = false;
bids.forEach(function (bid) {
if (bid.params.customParams) {
let customParamsForBid = utils._map(Object.keys(bid.params.customParams), customKey => formatCustomParms(customKey, bid.params.customParams));
Expand Down
8 changes: 8 additions & 0 deletions modules/openxBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Module that connects to OpenX's demand sources
{
bidder: 'openx',
params: {
placementId: '/123/abcdefg'
unit: '539439964',
delDomain: 'se-demo-d.openx.net'
}
Expand All @@ -46,3 +47,10 @@ Module that connects to OpenX's demand sources
}
];
```


# Links
[Banner Ads](https://docs.openx.com/Content/developers/containers/prebid-adapter.html)

[Video Ads](https://docs.openx.com/Content/developers/containers/prebid-video-adapter.html)

233 changes: 202 additions & 31 deletions test/spec/modules/openxBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,34 +129,43 @@ describe('OpenxAdapter', () => {

describe('isBidRequestValid', () => {
describe('when request is for a banner ad', () => {
const bannerBid = {
bidder: 'openx',
params: {
unit: '12345678',
delDomain: 'test-del-domain'
},
adUnitCode: 'adunit-code',
mediaTypes: {banner: {}},
sizes: [[300, 250], [300, 600]],
bidId: '30b31c1838de1e',
bidderRequestId: '22edbae2733bf6',
auctionId: '1d1a030790a475'
};

it('should return true when required params found', () => {
expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
let bannerBid;
beforeEach(() => {
bannerBid = {
bidder: 'openx',
params: {},
adUnitCode: 'adunit-code',
mediaTypes: {banner: {}},
sizes: [[300, 250], [300, 600]],
bidId: '30b31c1838de1e',
bidderRequestId: '22edbae2733bf6',
auctionId: '1d1a030790a475'
};
});

it('should return false when there is no delivery domain', () => {
let bid = Object.assign({}, bannerBid);
bid.params = {'unit': '12345678'};
expect(spec.isBidRequestValid(bid)).to.equal(false);
bannerBid.params = {'unit': '12345678'};
expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
});

it('should return false when there is no ad unit id ', () => {
let bid = Object.assign({}, bannerBid);
bid.params = {delDomain: 'test-del-domain'};
expect(spec.isBidRequestValid(bid)).to.equal(false);
describe('when there is a delivery domain', () => {
beforeEach(function () {
bannerBid.params = {delDomain: 'test-delivery-domain'}
});

it('should return false when there is no ad unit id and no placement id', () => {
expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
});

it('should return true if there is an adunit id ', () => {
bannerBid.params.unit = '12345678';
expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
});

it('should return true if there is an placement id ', () => {
bannerBid.params.placementId = '/12345678/aaaa/bbbb';
expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
});
});
});

Expand Down Expand Up @@ -186,7 +195,7 @@ describe('OpenxAdapter', () => {
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
'mediaTypes': 'video',
'mediaType': 'video',
'sizes': [640, 480],
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
Expand Down Expand Up @@ -233,7 +242,7 @@ describe('OpenxAdapter', () => {
const bidRequestsWithMediaTypes = [{
'bidder': 'openx',
'params': {
'unit': '12345678',
'unit': '11',
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
Expand All @@ -242,9 +251,24 @@ describe('OpenxAdapter', () => {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
'bidId': 'test-bid-id-1',
'bidderRequestId': 'test-bid-request-1',
'auctionId': 'test-auction-1'
}, {
'bidder': 'openx',
'params': {
'unit': '22',
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
'bidId': 'test-bid-id-2',
'bidderRequestId': 'test-bid-request-2',
'auctionId': 'test-auction-2'
}];

it('should send bid request to openx url via GET, with mediaType specified as banner', () => {
Expand All @@ -259,6 +283,153 @@ describe('OpenxAdapter', () => {
expect(request[0].method).to.equal('GET');
});

it('should send the adunit codes', () => {
const request = spec.buildRequests(bidRequestsWithMediaTypes);
expect(request[0].data.divs).to.equal(`${bidRequestsWithMediaTypes[0].adUnitCode},${bidRequestsWithMediaTypes[1].adUnitCode}`);
});

it('should send ad unit ids when any are defined', () => {
const bidRequestsWithPlacementIds = [{
'bidder': 'openx',
'params': {
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': 'test-bid-id-1',
'bidderRequestId': 'test-bid-request-1',
'auctionId': 'test-auction-1'
}, {
'bidder': 'openx',
'params': {
'unit': '22',
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
'bidId': 'test-bid-id-2',
'bidderRequestId': 'test-bid-request-2',
'auctionId': 'test-auction-2'
}];
const request = spec.buildRequests(bidRequestsWithPlacementIds);
expect(request[0].data.auid).to.equal(`,${bidRequestsWithPlacementIds[1].params.unit}`);
});

it('should not send any ad unit ids when none are defined', () => {
const bidRequestsWithoutPlacementIds = [{
'bidder': 'openx',
'params': {
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': 'test-bid-id-1',
'bidderRequestId': 'test-bid-request-1',
'auctionId': 'test-auction-1'
}, {
'bidder': 'openx',
'params': {
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
'bidId': 'test-bid-id-2',
'bidderRequestId': 'test-bid-request-2',
'auctionId': 'test-auction-2'
}];
const request = spec.buildRequests(bidRequestsWithoutPlacementIds);
expect(request[0].data).to.not.have.any.keys('auid');
});

it('should send placement ids when any are defined', () => {
const bidRequestsWithPlacementIds = [{
'bidder': 'openx',
'params': {
'unit': '11',
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': 'test-bid-id-1',
'bidderRequestId': 'test-bid-request-1',
'auctionId': 'test-auction-1'
}, {
'bidder': 'openx',
'params': {
'unit': '22',
'delDomain': 'test-del-domain',
placementId: 'test-placement-id-2'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
'bidId': 'test-bid-id-2',
'bidderRequestId': 'test-bid-request-2',
'auctionId': 'test-auction-2'
}];
const request = spec.buildRequests(bidRequestsWithPlacementIds);
expect(request[0].data.pids).to.equal(`,${bidRequestsWithPlacementIds[1].params.placementId}`);
});

it('should not send any placement ids when none are defined', () => {
const bidRequestsWithoutPlacementIds = [{
'bidder': 'openx',
'params': {
'unit': '11',
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': 'test-bid-id-1',
'bidderRequestId': 'test-bid-request-1',
'auctionId': 'test-auction-1'
}, {
'bidder': 'openx',
'params': {
'unit': '22',
'delDomain': 'test-del-domain'
},
'adUnitCode': 'adunit-code',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
},
'bidId': 'test-bid-id-2',
'bidderRequestId': 'test-bid-request-2',
'auctionId': 'test-auction-2'
}];
const request = spec.buildRequests(bidRequestsWithoutPlacementIds);
expect(request[0].data).to.not.have.any.keys('pids');
});

describe('when there is a legacy request with no media type', function () {
const deprecatedBidRequestsFormatWithNoMediaType = [{
'bidder': 'openx',
Expand Down Expand Up @@ -1077,10 +1248,10 @@ describe('OpenxAdapter', () => {

it('should register the pixel iframe from banner ad response', () => {
let syncs = spec.getUserSyncs(
{ iframeEnabled: true },
[{ body: { ads: { pixels: syncUrl } } }]
{iframeEnabled: true},
[{body: {ads: {pixels: syncUrl}}}]
);
expect(syncs).to.deep.equal([{ type: 'iframe', url: syncUrl }]);
expect(syncs).to.deep.equal([{type: 'iframe', url: syncUrl}]);
});

it('should register the pixel iframe from video ad response', () => {
Expand Down

0 comments on commit f288c98

Please sign in to comment.