mk9-prebid
Version:
Header Bidding Management Library
752 lines (716 loc) • 25 kB
JavaScript
import { expect } from 'chai'
import { spec, validateGeoObject, getDomain } from '../../../modules/apacdexBidAdapter.js'
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)
describe('.code', function () {
it('should return a bidder code of apacdex', function () {
expect(spec.code).to.equal('apacdex')
})
})
describe('inherited functions', function () {
it('should exist and be a function', function () {
expect(adapter.callBids).to.exist.and.to.be.a('function')
})
})
describe('.isBidRequestValid', function () {
it('should return false if there are no params', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
'mediaTypes': {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
it('should return false if there is no siteId or placementId param', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
params: {
site_id: '1a2b3c4d5e6f1a2b3c4d',
placement_id: 'plcm12345678',
},
'mediaTypes': {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
it('should return false if there is no mediaTypes', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
params: {
siteId: '1a2b3c4d5e6f1a2b3c4d'
},
'mediaTypes': {
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
it('should return true if the bid is valid', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
params: {
siteId: '1a2b3c4d5e6f1a2b3c4d'
},
'mediaTypes': {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(true);
});
describe('banner', () => {
it('should return false if there are no banner sizes', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
params: {
siteId: '1a2b3c4d5e6f1a2b3c4d'
},
'mediaTypes': {
banner: {
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
it('should return true if there is banner sizes', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
params: {
siteId: '1a2b3c4d5e6f1a2b3c4d'
},
'mediaTypes': {
banner: {
sizes: [[300, 250], [300, 600]]
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(true);
});
});
describe('video', () => {
it('should return false if there is no playerSize defined in the video mediaType', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
params: {
siteId: '1a2b3c4d5e6f1a2b3c4d',
sizes: [[300, 250], [300, 600]]
},
'mediaTypes': {
video: {
context: 'instream'
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
it('should return true if there is playerSize defined on the video mediaType', () => {
const bid = {
'bidder': 'apacdex',
'adUnitCode': 'adunit-code',
params: {
siteId: '1a2b3c4d5e6f1a2b3c4d',
},
'mediaTypes': {
video: {
context: 'instream',
playerSize: [[640, 480]]
}
},
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};
expect(spec.isBidRequestValid(bid)).to.equal(true);
});
});
});
describe('.buildRequests', function () {
beforeEach(function () {
sinon.stub(userSync, 'canBidderRegisterSync');
});
afterEach(function () {
userSync.canBidderRegisterSync.restore();
});
let bidRequest = [{
'schain': {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'indirectseller.com',
'sid': '00001',
'hp': 1
},
{
'asi': 'indirectseller-2.com',
'sid': '00002',
'hp': 0
},
]
},
'bidder': 'apacdex',
'params': {
'siteId': '1a2b3c4d5e6f1a2b3c4d',
'geo': { 'lat': 123.13123456, 'lon': 54.23467311, 'accuracy': 60 }
},
'adUnitCode': 'adunit-code-1',
'sizes': [[300, 250], [300, 600]],
'targetKey': 0,
'bidId': '30b31c1838de1f',
'userIdAsEids': [{
'source': 'criteo.com',
'uids': [{
'id': 'p0cCLF9JazY1ZUFjazJRb3NKbEprVTcwZ0IwRUlGalBjOG9laUZNbFJ0ZGpOSnVFbE9VMjBNMzNBTzladGt4cUVGQzBybDY2Y1FqT1dkUkFsMmJIWDRHNjlvNXJjbiUyQlZDd1dOTmt6VlV2TDhRd0F0RTlBcmpyZU5WRHBPU25GQXpyMnlT',
'atype': 1
}]
}, {
'source': 'pubcid.org',
'uids': [{
'id': '2ae366c2-2576-45e5-bd21-72ed10598f17',
'atype': 1
}]
}],
},
{
'bidder': 'apacdex',
'params': {
'ad_unit': '/7780971/sparks_prebid_LB',
'sizes': [[300, 250], [300, 600]],
'referrer': 'overrides_top_window_location'
},
'adUnitCode': 'adunit-code-2',
'sizes': [[120, 600], [300, 600], [160, 600]],
'targetKey': 1,
'bidId': '30b31c1838de1e',
}];
let bidderRequests = {
'gdprConsent': {
'consentString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
'vendorData': {},
'gdprApplies': true
},
'refererInfo': {
'numIframes': 0,
'reachedTop': true,
'referer': 'https://example.com',
'stack': ['https://example.com']
},
uspConsent: 'someCCPAString'
};
it('should return a properly formatted request', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests)
expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex')
expect(bidRequests.method).to.equal('POST')
expect(bidRequests.bidderRequests).to.eql(bidRequest);
})
it('should return a properly formatted request with GDPR applies set to true', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests)
expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex')
expect(bidRequests.method).to.equal('POST')
expect(bidRequests.data.gdpr.gdprApplies).to.equal(true)
expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==')
})
it('should return a properly formatted request with GDPR applies set to false', function () {
bidderRequests.gdprConsent.gdprApplies = false;
const bidRequests = spec.buildRequests(bidRequest, bidderRequests)
expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex')
expect(bidRequests.method).to.equal('POST')
expect(bidRequests.data.gdpr.gdprApplies).to.equal(false)
expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==')
})
it('should return a properly formatted request with GDPR applies set to false with no consent_string param', function () {
let bidderRequests = {
'gdprConsent': {
'consentString': undefined,
'vendorData': {},
'gdprApplies': false
},
'refererInfo': {
'numIframes': 0,
'reachedTop': true,
'referer': 'https://example.com',
'stack': ['https://example.com']
}
};
const bidRequests = spec.buildRequests(bidRequest, bidderRequests)
expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex')
expect(bidRequests.method).to.equal('POST')
expect(bidRequests.data.gdpr.gdprApplies).to.equal(false)
expect(bidRequests.data.gdpr).to.not.include.keys('consentString')
})
it('should return a properly formatted request with GDPR applies set to true with no consentString param', function () {
let bidderRequests = {
'gdprConsent': {
'consentString': undefined,
'vendorData': {},
'gdprApplies': true
},
'refererInfo': {
'numIframes': 0,
'reachedTop': true,
'referer': 'https://example.com',
'stack': ['https://example.com']
}
};
const bidRequests = spec.buildRequests(bidRequest, bidderRequests)
expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex')
expect(bidRequests.method).to.equal('POST')
expect(bidRequests.data.gdpr.gdprApplies).to.equal(true)
expect(bidRequests.data.gdpr).to.not.include.keys('consentString')
})
it('should return a properly formatted request with schain defined', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.schain).to.deep.equal(bidRequest[0].schain)
});
it('should return a properly formatted request with eids defined', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.eids).to.deep.equal(bidRequest[0].userIdAsEids)
});
it('should return a properly formatted request with geo defined', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.geo).to.deep.equal(bidRequest[0].params.geo)
});
it('should return a properly formatted request with us_privacy included', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.us_privacy).to.equal('someCCPAString');
});
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 });
});
it('should return a properly formatted request with pbjs_debug is true', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.test).to.equal(1);
});
});
});
describe('.interpretResponse', function () {
const bidRequests = {
'method': 'POST',
'url': 'https://useast.quantumdex.io/auction/apacdex',
'withCredentials': true,
'data': {
'device': {
'ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
'height': 937,
'width': 1920,
'dnt': 0,
'language': 'vi'
},
'site': {
'id': '343',
'page': 'https://www.example.com/page',
'referrer': '',
'hostname': 'www.example.com'
}
},
'bidderRequests': [
{
'bidder': 'apacdex',
'params': {
'siteId': '343'
},
'crumbs': {
'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff'
},
'mediaTypes': {
'banner': {
'sizes': [[160, 600], [120, 600]]
}
},
'adUnitCode': 'vi_3431035_1',
'transactionId': '994d8404-4a28-4c43-98d8-a38dbb061910',
'sizes': [[160, 600], [120, 600]],
'bidId': '3000aa31c41a29c21',
'bidderRequestId': '299926b3d3628cdd7',
'auctionId': '22445943-a0aa-4c63-a413-4deb64fcff1c',
'src': 'client',
'bidRequestsCount': 41,
'bidderRequestsCount': 41,
'bidderWinsCount': 0,
'schain': {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'freegames66.com',
'sid': '343',
'hp': 1
}
]
}
},
{
'bidder': 'apacdex',
'params': {
'siteId': '343'
},
'crumbs': {
'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff'
},
'mediaTypes': {
'banner': {
'sizes': [[300, 250], [250, 250], [200, 200], [180, 150]]
}
},
'adUnitCode': 'vi_3431033_1',
'transactionId': '800fe87e-bfec-43a5-ace0-c4e2373ff4b5',
'sizes': [[300, 250], [250, 250], [200, 200], [180, 150]],
'bidId': '30024615be22ef66a',
'bidderRequestId': '299926b3d3628cdd7',
'auctionId': '22445943-a0aa-4c63-a413-4deb64fcff1c',
'src': 'client',
'bidRequestsCount': 41,
'bidderRequestsCount': 41,
'bidderWinsCount': 0,
'schain': {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'freegames66.com',
'sid': '343',
'hp': 1
}
]
}
},
{
'bidder': 'apacdex',
'params': {
'siteId': '343'
},
'crumbs': {
'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff'
},
'mediaTypes': {
'video': {
'playerSize': [[640, 480]],
'context': 'instream',
'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'
],
'protocols': [1, 2, 3, 4, 5, 6],
'playbackmethod': [6],
'maxduration': 120,
'linearity': 1,
'api': [2]
}
},
'adUnitCode': 'vi_3431909',
'transactionId': '33d83d87-43cc-499b-aabe-5c22eb6acfbb',
'sizes': [[640, 480]],
'bidId': '1854b40107d6745c',
'bidderRequestId': '1840763b6bda185d',
'auctionId': 'df495de0-5d42-471f-a501-73bcd7254b80',
'src': 'client',
'bidRequestsCount': 1,
'bidderRequestsCount': 1,
'bidderWinsCount': 0,
'schain': {
'ver': '1.0',
'complete': 1,
'nodes': [
{
'asi': 'freegames66.com',
'sid': '343',
'hp': 1
}
]
}
}
]
};
let serverResponse = {
'body': {
'bids': [
{
'requestId': '3000aa31c41a29c21',
'cpm': 1.07,
'width': 160,
'height': 600,
'ad': `<div>Apacdex AD</div>`,
'ttl': 500,
'creativeId': '1234abcd',
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'banner',
'meta': {
'advertiserDomains': ['https://example.com']
}
},
{
'requestId': '30024615be22ef66a',
'cpm': 1,
'width': 300,
'height': 250,
'ad': `<div>Apacdex AD</div>`,
'ttl': 500,
'creativeId': '1234abcd',
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'banner',
'meta': {
'advertiserDomains': ['https://example.com']
}
},
{
'requestId': '1854b40107d6745c',
'cpm': 1.25,
'width': 300,
'height': 250,
'vastXml': '<VAST><Ad id="20001"><InLine><AdSystem version="4.0">apacdex</AdSystem></InLine></Ad></VAST>',
'ttl': 500,
'creativeId': '30292e432662bd5f86d90774b944b038',
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'video',
'meta': {
'advertiserDomains': ['https://example.com']
}
}
],
'pixel': [{
'url': 'https://example.com/pixel.png',
'type': 'image'
}]
}
};
let prebidResponse = [
{
'requestId': '3000aa31c41a29c21',
'cpm': 1.07,
'width': 160,
'height': 600,
'ad': `<div>Apacdex AD</div>`,
'ttl': 500,
'creativeId': '1234abcd',
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'banner'
},
{
'requestId': '30024615be22ef66a',
'cpm': 1,
'width': 300,
'height': 250,
'ad': `<div>Apacdex AD</div>`,
'ttl': 500,
'creativeId': '1234abcd',
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'banner'
},
{
'requestId': '1854b40107d6745c',
'cpm': 1.25,
'width': 300,
'height': 250,
'vastXml': '<VAST><Ad id="20001"><InLine><AdSystem version="4.0">apacdex</AdSystem></InLine></Ad></VAST>',
'ttl': 500,
'creativeId': '30292e432662bd5f86d90774b944b038',
'netRevenue': true,
'currency': 'USD',
'dealId': 'apacdex',
'mediaType': 'video'
}
];
it('should map bidResponse to prebidResponse', function () {
const response = spec.interpretResponse(serverResponse, bidRequests);
response.forEach((resp, i) => {
expect(resp.requestId).to.equal(prebidResponse[i].requestId);
expect(resp.cpm).to.equal(prebidResponse[i].cpm);
expect(resp.width).to.equal(prebidResponse[i].width);
expect(resp.height).to.equal(prebidResponse[i].height);
expect(resp.ttl).to.equal(prebidResponse[i].ttl);
expect(resp.creativeId).to.equal(prebidResponse[i].creativeId);
expect(resp.netRevenue).to.equal(prebidResponse[i].netRevenue);
expect(resp.currency).to.equal(prebidResponse[i].currency);
expect(resp.dealId).to.equal(prebidResponse[i].dealId);
if (resp.mediaType === 'video') {
expect(resp.vastXml.indexOf('apacdex')).to.be.greaterThan(0);
}
if (resp.mediaType === 'banner') {
expect(resp.ad.indexOf('Apacdex AD')).to.be.greaterThan(0);
}
expect(resp.meta.advertiserDomains).to.deep.equal(['https://example.com']);
});
});
});
describe('.getUserSyncs', function () {
let bidResponse = [{
'body': {
'pixel': [{
'url': 'https://pixel-test',
'type': 'image'
}]
}
}];
it('should return one sync pixel', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.deep.equal([{
type: 'image',
url: 'https://pixel-test'
}]);
});
it('should return an empty array when sync is enabled but there are no bidResponses', function () {
expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0);
});
it('should return an empty array when sync is enabled but no sync pixel returned', function () {
const pixel = Object.assign({}, bidResponse);
delete pixel[0].body.pixel;
expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.have.length(0);
});
it('should return an empty array', function () {
expect(spec.getUserSyncs({ pixelEnabled: false }, bidResponse)).to.have.length(0);
expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0);
});
});
describe('validateGeoObject', function () {
it('should return true if the geo object is valid', () => {
let geoObject = {
lat: 123.5624234,
lon: 23.6712341,
accuracy: 20
};
expect(validateGeoObject(geoObject)).to.equal(true);
});
it('should return false if the geo object is not plain object', () => {
let geoObject = [{
lat: 123.5624234,
lon: 23.6712341,
accuracy: 20
}];
expect(validateGeoObject(geoObject)).to.equal(false);
});
it('should return false if the geo object is missing lat attribute', () => {
let geoObject = {
lon: 23.6712341,
accuracy: 20
};
expect(validateGeoObject(geoObject)).to.equal(false);
});
it('should return false if the geo object is missing lon attribute', () => {
let geoObject = {
lat: 123.5624234,
accuracy: 20
};
expect(validateGeoObject(geoObject)).to.equal(false);
});
it('should return false if the geo object is missing accuracy attribute', () => {
let geoObject = {
lat: 123.5624234,
lon: 23.6712341
};
expect(validateGeoObject(geoObject)).to.equal(false);
});
});
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 });
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: '' });
expect(getDomain(pageUrl)).to.equal('example.com');
});
it('should return undefined if pageUrl and publisherDomain not config', () => {
let pageUrl;
config.setConfig({ publisherDomain: '' });
expect(getDomain(pageUrl)).to.equal(pageUrl);
});
});
});