Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apacdex Bid Adapter: add support for meta.advertiserDomains, add and update sample adunit, validate dealId field from server response, add support Price Floors Module #6711

Merged
merged 5 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions modules/apacdexBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ export const spec = {
let eids;
let geo;
let test;
let bids = [];

var bids = JSON.parse(JSON.stringify(validBidRequests))
bidderConfig = CONFIG[bids[0].bidder];
bidderConfig = CONFIG[validBidRequests[0].bidder];

test = config.getConfig('debug');

bids.forEach(bidReq => {
validBidRequests.forEach(bidReq => {
siteId = siteId || bidReq.params.siteId;

if (bidReq.schain) {
Expand Down Expand Up @@ -95,6 +95,13 @@ export const spec = {
}
bySlotTargetKey[bidReq.adUnitCode] = targetKey;
bidReq.targetKey = targetKey;

let bidFloor = getBidFloor(bidReq);
if (bidFloor) {
bidReq.bidFloor = bidFloor;
}

bids.push(JSON.parse(JSON.stringify(bidReq)));
});

const payload = {};
Expand Down Expand Up @@ -169,23 +176,30 @@ export const spec = {

const bidResponses = [];
serverBids.forEach(bid => {
const dealId = bid.dealId || '';
const bidResponse = {
requestId: bid.requestId,
cpm: bid.cpm,
width: bid.width,
height: bid.height,
creativeId: bid.creativeId,
dealId: bid.dealId,
currency: bid.currency,
netRevenue: bid.netRevenue,
ttl: bid.ttl,
mediaType: bid.mediaType
};
if (dealId.length > 0) {
bidResponse.dealId = dealId;
}
if (bid.vastXml) {
bidResponse.vastXml = utils.replaceAuctionPrice(bid.vastXml, bid.cpm);
} else {
bidResponse.ad = utils.replaceAuctionPrice(bid.ad, bid.cpm);
}
bidResponse.meta = {};
if (bid.meta && bid.meta.advertiserDomains && utils.isArray(bid.meta.advertiserDomains)) {
bidResponse.meta.advertiserDomains = bid.meta.advertiserDomains;
}
bidResponses.push(bidResponse);
});
return bidResponses;
Expand Down Expand Up @@ -336,4 +350,26 @@ export function validateGeoObject(geo) {
return true;
}

/**
* Get bid floor from Price Floors Module
*
* @param {Object} bid
* @returns {float||null}
*/
function getBidFloor(bid) {
if (!utils.isFn(bid.getFloor)) {
return (bid.params.floorPrice) ? bid.params.floorPrice : null;
}

let floor = bid.getFloor({
currency: 'USD',
mediaType: '*',
size: '*'
});
if (utils.isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') {
return floor.floor;
}
return null;
}

registerBidder(spec);
56 changes: 52 additions & 4 deletions modules/apacdexBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Maintainer: ken@apacdex.com
Connects to APAC Digital Exchange for bids.
Apacdex bid adapter supports Banner and Video (Instream and Outstream) ads.

# Test Parameters
# Sample Banner Ad Unit
```
var adUnits = [
{
Expand All @@ -26,31 +26,79 @@ var adUnits = [
bidder: 'apacdex',
params: {
siteId: 'apacdex1234', // siteId provided by Apacdex
floorPrice: 0.01, // default is 0.01 if not declared
}
}
]
}
];
```

# Video Test Parameters
# Sample Video Ad Unit: Instream
```
var videoAdUnit = {
code: 'test-div',
sizes: [[640, 480]],
mediaTypes: {
video: {
playerSize: [[640, 480]],
context: 'instream'
context: "instream"
api: [2],
placement: 1,
skip: 1,
linearity: 1,
minduration: 1,
maxduration: 120,
mimes: ["video/mp4", "video/x-flv", "video/x-ms-wmv", "application/vnd.apple.mpegurl", "application/x-mpegurl", "video/3gpp", "video/mpeg", "video/ogg", "video/quicktime", "video/webm", "video/x-m4v", "video/ms-asf", video/x-msvideo"],
playbackmethod: [6],
startdelay: 0,
protocols: [1, 2, 3, 4, 5, 6]
},
},
bids: [
{
bidder: 'apacdex',
params: {
siteId: 'apacdex1234', // siteId provided by Apacdex
floorPrice: 0.01, // default is 0.01 if not declared
thuyhq marked this conversation as resolved.
Show resolved Hide resolved
}
}
]
};
```
```
mediaTypes.video object reference to section 3.2.7 Object: Video in the OpenRTB 2.5 document
You must review all video parameters to ensure validity for your player and DSPs

# Sample Video Ad Unit: Outstream
```
var videoAdUnit = {
code: 'test-div',
sizes: [[410, 231]],
mediaTypes: {
video: {
playerSize: [[410, 231]],
context: "outstream"
api: [2],
placement: 5,
linearity: 1,
minduration: 1,
maxduration: 120,
mimes: ["video/mp4", "video/x-flv", "video/x-ms-wmv", "application/vnd.apple.mpegurl", "application/x-mpegurl", "video/3gpp", "video/mpeg", "video/ogg", "video/quicktime", "video/webm", "video/x-m4v", "video/ms-asf", video/x-msvideo"],
playbackmethod: [6],
startdelay: 0,
protocols: [1, 2, 3, 4, 5, 6]
},
},
bids: [
{
bidder: 'apacdex',
params: {
siteId: 'apacdex1234', // siteId provided by Apacdex
floorPrice: 0.01, // default is 0.01 if not declared
thuyhq marked this conversation as resolved.
Show resolved Hide resolved
}
}
]
};
```
mediaTypes.video object reference to section 3.2.7 Object: Video in the OpenRTB 2.5 document
You must review all video parameters to ensure validity for your player and DSPs
73 changes: 61 additions & 12 deletions test/spec/modules/apacdexBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { spec, validateGeoObject, getDomain } from '../../../modules/apacdexBidA
import { newBidder } from 'src/adapters/bidderFactory.js'
import { userSync } from '../../../src/userSync.js';
import { config } from 'src/config.js';
import { deepClone } from 'src/utils.js';

describe('ApacdexBidAdapter', function () {
const adapter = newBidder(spec)
Expand Down Expand Up @@ -200,7 +201,7 @@ describe('ApacdexBidAdapter', function () {
'bidder': 'apacdex',
'params': {
'siteId': '1a2b3c4d5e6f1a2b3c4d',
'geo': {'lat': 123.13123456, 'lon': 54.23467311, 'accuracy': 60}
'geo': { 'lat': 123.13123456, 'lon': 54.23467311, 'accuracy': 60 }
},
'adUnitCode': 'adunit-code-1',
'sizes': [[300, 250], [300, 600]],
Expand Down Expand Up @@ -336,12 +337,50 @@ describe('ApacdexBidAdapter', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.us_privacy).to.equal('someCCPAString');
});
describe('debug test', function() {
beforeEach(function() {
config.setConfig({debug: true});
it('should attach bidFloor param when either bid param floorPrice or getFloor function exists', function () {
let getFloorResponse = { currency: 'USD', floor: 3 };
let singleBidRequest, request, payload = null;

// 1 -> floorPrice not defined, getFloor not defined > empty
singleBidRequest = deepClone(bidRequest[0]);
request = spec.buildRequests([singleBidRequest], bidderRequests);
payload = request.data;
expect(payload.bids[0].bidFloor).to.not.exist;

// 2 -> floorPrice is defined, getFloor not defined > floorPrice is used
singleBidRequest = deepClone(bidRequest[0]);
singleBidRequest.params = {
'siteId': '1890909',
'floorPrice': 0.5
};
request = spec.buildRequests([singleBidRequest], bidderRequests);
payload = request.data
expect(payload.bids[0].bidFloor).to.exist.and.to.equal(0.5);

// 3 -> floorPrice is defined, getFloor is defined > getFloor is used
singleBidRequest = deepClone(bidRequest[0]);
singleBidRequest.params = {
'siteId': '1890909',
'floorPrice': 0.5
};
singleBidRequest.getFloor = () => getFloorResponse;
request = spec.buildRequests([singleBidRequest], bidderRequests);
payload = request.data
expect(payload.bids[0].bidFloor).to.exist.and.to.equal(3);

// 4 -> floorPrice not defined, getFloor is defined > getFloor is used
singleBidRequest = deepClone(bidRequest[0]);
singleBidRequest.getFloor = () => getFloorResponse;
request = spec.buildRequests([singleBidRequest], bidderRequests);
payload = request.data
expect(payload.bids[0].bidFloor).to.exist.and.to.equal(3);
});
describe('debug test', function () {
beforeEach(function () {
config.setConfig({ debug: true });
});
afterEach(function() {
config.setConfig({debug: false});
afterEach(function () {
config.setConfig({ debug: false });
});
it('should return a properly formatted request with pbjs_debug is true', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
Expand Down Expand Up @@ -514,7 +553,10 @@ describe('ApacdexBidAdapter', function () {
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'banner'
'mediaType': 'banner',
'meta': {
'advertiserDomains': ['https://example.com']
}
},
{
'requestId': '30024615be22ef66a',
Expand All @@ -527,7 +569,10 @@ describe('ApacdexBidAdapter', function () {
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'banner'
'mediaType': 'banner',
'meta': {
'advertiserDomains': ['https://example.com']
}
},
{
'requestId': '1854b40107d6745c',
Expand All @@ -540,7 +585,10 @@ describe('ApacdexBidAdapter', function () {
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'video'
'mediaType': 'video',
'meta': {
'advertiserDomains': ['https://example.com']
}
}
],
'pixel': [{
Expand Down Expand Up @@ -610,6 +658,7 @@ describe('ApacdexBidAdapter', function () {
if (resp.mediaType === 'banner') {
expect(resp.ad.indexOf('Apacdex AD')).to.be.greaterThan(0);
}
expect(resp.meta.advertiserDomains).to.deep.equal(['https://example.com']);
});
});
});
Expand Down Expand Up @@ -693,17 +742,17 @@ describe('ApacdexBidAdapter', function () {
describe('getDomain', function () {
it('should return valid domain from publisherDomain config', () => {
let pageUrl = 'https://www.example.com/page/prebid/exam.html';
config.setConfig({publisherDomain: pageUrl});
config.setConfig({ publisherDomain: pageUrl });
expect(getDomain(pageUrl)).to.equal('example.com');
});
it('should return valid domain from pageUrl argument', () => {
let pageUrl = 'https://www.example.com/page/prebid/exam.html';
config.setConfig({publisherDomain: ''});
config.setConfig({ publisherDomain: '' });
expect(getDomain(pageUrl)).to.equal('example.com');
});
it('should return undefined if pageUrl and publisherDomain not config', () => {
let pageUrl;
config.setConfig({publisherDomain: ''});
config.setConfig({ publisherDomain: '' });
expect(getDomain(pageUrl)).to.equal(pageUrl);
});
});
Expand Down