mk9-prebid
Version:
Header Bidding Management Library
1,399 lines (1,216 loc) • 105 kB
JavaScript
import { expect } from 'chai';
import { PrebidServer as Adapter, resetSyncedStatus, resetWurlMap } from 'modules/prebidServerBidAdapter/index.js';
import adapterManager from 'src/adapterManager.js';
import * as utils from 'src/utils.js';
import { ajax } from 'src/ajax.js';
import { config } from 'src/config.js';
import events from 'src/events.js';
import CONSTANTS from 'src/constants.json';
import { server } from 'test/mocks/xhr.js';
import { createEidsArray } from 'modules/userId/eids.js';
let CONFIG = {
accountId: '1',
enabled: true,
bidders: ['appnexus'],
timeout: 1000,
cacheMarkup: 2,
endpoint: {
p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction',
noP1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
}
};
const REQUEST = {
'account_id': '1',
'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5',
'max_bids': 1,
'timeout_millis': 1000,
'secure': 0,
'url': '',
'prebid_version': '0.30.0-pre',
's2sConfig': CONFIG,
'ad_units': [
{
'code': 'div-gpt-ad-1460505748561-0',
'sizes': [[300, 250], [300, 600]],
'mediaTypes': {
'banner': {
'sizes': [[300, 250], [300, 300]]
},
'native': {
'title': {
'required': true,
'len': 800
},
'image': {
'required': true,
'sizes': [989, 742],
},
'icon': {
'required': true,
'aspect_ratios': [{
'min_height': 10,
'min_width': 10,
'ratio_height': 1,
'ratio_width': 1
}]
},
'sponsoredBy': {
'required': true
}
}
},
'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c',
'bids': [
{
'bid_id': '123',
'bidder': 'appnexus',
'params': {
'placementId': '10433394',
'member': 123
}
}
]
}
]
};
const VIDEO_REQUEST = {
'account_id': '1',
'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5',
'max_bids': 1,
'timeout_millis': 1000,
'secure': 0,
'url': '',
'prebid_version': '1.4.0-pre',
's2sConfig': CONFIG,
'ad_units': [
{
'code': 'div-gpt-ad-1460505748561-0',
'sizes': [640, 480],
'mediaTypes': {
'video': {
'playerSize': [[640, 480]],
'mimes': ['video/mp4']
}
},
'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c',
'bids': [
{
'bid_id': '123',
'bidder': 'appnexus',
'params': { 'placementId': '12349520' }
}
]
}
]
};
const OUTSTREAM_VIDEO_REQUEST = {
'account_id': '1',
'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5',
'max_bids': 1,
'timeout_millis': 1000,
'secure': 0,
'url': '',
'prebid_version': '1.4.0-pre',
's2sConfig': CONFIG,
'ad_units': [
{
'code': 'div-gpt-ad-1460505748561-0',
'sizes': [640, 480],
'mediaTypes': {
'video': {
playerSize: [[640, 480]],
context: 'outstream',
mimes: ['video/mp4'],
renderer: {
url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
render: function (bid) {
ANOutstreamVideo.renderAd({
targetId: bid.adUnitCode,
adResponse: bid.adResponse,
});
}
}
},
banner: { sizes: [[300, 250]] }
},
'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c',
'bids': [
{
'bid_id': '123',
'bidder': 'appnexus',
'params': { 'placementId': '12349520' }
}
]
},
{
code: 'video1',
mediaTypes: {
video: {
playerSize: [640, 480],
context: 'outstream',
mimes: ['video/mp4'],
skip: 1
}
},
bids: [
{
bidder: 'appnexus',
params: {
placementId: 13232385,
video: {
skippable: true,
playback_method: ['auto_play_sound_off']
}
}
}
]
}
],
};
let BID_REQUESTS;
const RESPONSE_NO_BID_NO_UNIT = {
'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5',
'status': 'OK',
'bidder_status': [{
'bidder': 'appnexus',
'response_time_ms': 132,
'no_bid': true
}]
};
const RESPONSE_NO_BID_UNIT_SET = {
'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5',
'status': 'OK',
'bidder_status': [{
'bidder': 'appnexus',
'ad_unit': 'div-gpt-ad-1460505748561-0',
'response_time_ms': 91,
'no_bid': true
}]
};
const RESPONSE_NO_COOKIE = {
'tid': 'd6eca075-4a59-4346-bdb3-86531830ef2c',
'status': 'OK',
'bidder_status': [{
'bidder': 'pubmatic',
'no_cookie': true,
'usersync': {
'url': '//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=http://localhost:8000/setuid?bidder=pubmatic&uid=',
'type': 'iframe'
}
}]
};
const RESPONSE_NO_PBS_COOKIE = {
'tid': '882fe33e-2981-4257-bd44-bd3b03945f48',
'status': 'no_cookie',
'bidder_status': [{
'bidder': 'rubicon',
'no_cookie': true,
'usersync': {
'url': 'https://pixel.rubiconproject.com/exchange/sync.php?p=prebid',
'type': 'redirect'
}
}, {
'bidder': 'pubmatic',
'no_cookie': true,
'usersync': {
'url': '//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=https%3A%2F%2Fprebid.adnxs.com%2Fpbs%2Fv1%2Fsetuid%3Fbidder%3Dpubmatic%26uid%3D',
'type': 'iframe'
}
}, {
'bidder': 'appnexus',
'response_time_ms': 162,
'num_bids': 1,
'debug': [{
'request_uri': 'http://ib.adnxs.com/openrtb2',
'request_body': '{"id":"882fe33e-2981-4257-bd44-bd3b03945f48","imp":[{"id":"/19968336/header-bid-tag-0","banner":{"w":300,"h":250,"format":[{"w":300,"h":250}]},"secure":1,"ext":{"appnexus":{"placement_id":5914989}}}],"site":{"domain":"nytimes.com","page":"http://www.nytimes.com"},"device":{"ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36","ip":"75.97.0.47"},"user":{"id":"3519479852893340159","buyeruid":"3519479852893340159"},"at":1,"tmax":1000,"source":{"fd":1,"tid":"882fe33e-2981-4257-bd44-bd3b03945f48"}}',
'response_body': '{"id":"882fe33e-2981-4257-bd44-bd3b03945f48"}',
'status_code': 200
}]
}],
'bids': [{
'bid_id': '123',
'code': 'div-gpt-ad-1460505748561-0',
'creative_id': '70928274',
'bidder': 'appnexus',
'price': 0.07425,
'adm': '<script type="application/javascript" src="https://secure-nym.adnxs.com/ab?e=wqT_3QLeCPBOXgQAAAMA1gAFAQi5krDKBRCwho2ft8LKoCMY_4PozveI7eswIAEqLQnbgoxDEVi5PxElYqnyDAKzPxkAAAAgXA8zQCHOzMzMzMy8PykzMwECsMM_MO2C6QI47RtA_AxIAlCSj-khWL-tNGAAaNfUTniivwSAAQGKAQNVU0SSAQEG8FSYAawCoAH6AagBAbABALgBAsABBcgBAtABCdgBAOABAPABAIoCkgF1ZignYScsIDE2OTc2MjksIDE0OTgxNTUzMjEpO3VmKCdyJywgNzA5MjgyNzQsQh4ABGMnATsQODY2NTVKPAAgZycsIDM5OTgzTh0AKGknLCA0OTM1MTUsMlcA8IeSAs0CIWhWRE5jZ2pfdVlVSUVKS1A2U0VZQUNDX3JUUXdBRGdBUUFCSV9BeFE3WUxwQWxnQVlKOEJhQUJ3QUhnQWdBRUFpQUVBa0FFQm1BRUJvQUVCcUFFRHNBRUF1UUhPRGRmZE16UERQOEVCemczWDNUTXp3el9KQVFBQUFBQUFBUEFfMlFFCQw0QUR3UC1BQnk0OGU5UUUFFChnQUlCaUFLMzdjRQEIQEIzNWNCaUFMZzZJNEVpQUxoDQgAag0IAG4NCABvAQhIa0FJSG1BSUFvQUlBcUFJR3RRSQVUAHYNCPBed0FJQXlBSUEwQUlBMkFJQTRBTDYtd2ZvQXBqaXI4b0Y4Z0lGZG1semFUSDRBZ0NBQXdHUUF3Q1lBd0dvQV8tNWhRaTZBd2xPV1UweU9qTTJNamcumgItIV93ajdud2oyUAHwTHY2MDBJQUFvQURvSlRsbE5Nam96TmpJNNgCAOACvtUr6gIWaHR0cDovL3d3dy5ueXRpbWVzLmNvbfICEQoGQURWX0lEEgcxNjk3NjI5BRQIQ1BHBRQt9AEUCAVDUAETBAgxTSXA8gINCghBRFZfRlJFURIBMPICGQoPQ1VTVE9NX01PREVMX0lEEgYxMzA1NTTyAh8KFjIcAFBMRUFGX05BTUUSBXZpc2kx8gIoCho2IgAIQVNUAUkcSUZJRUQSCjFBzvB4NDkxNDSAAwCIAwGQAwCYAxSgAwGqAwDAA6wCyAMA2APjBuADAOgDAPgDA4AEAJIECS9vcGVucnRiMpgEAKIECjc1Ljk3LjAuNDeoBACyBAoIABAAGAAgADAAuAQAwAQAyAQA0gQJTllNMjozNjI42gQCCAHgBADwBGGlIIgFAZgFAKAF_xEBuAGqBSQ4ODJmZTMzZS0yOTgxLTQyNTctYmQ0NC1iZDNiMDM5NDVmNDjABQDJBQAAAQI08D_SBQkJAAAAAAAAAAA.&s=d4bc7cd2e5d7e1910a591bc97df6ae9e63333e52&referrer=http%3A%2F%2Fwww.nytimes.com&pp=${AUCTION_PRICE}&"></script>',
'width': 300,
'height': 250,
'response_time_ms': 162
}]
};
const RESPONSE_OPENRTB = {
'id': 'c7dcf14f',
'seatbid': [
{
'bid': [
{
'id': '8750901685062148',
'impid': 'div-gpt-ad-1460505748561-0',
'price': 0.5,
'adm': '<script src="http://lax1-ib.adnxs.com/ab?e=wqT_3QKgB6CgAwAAAwDWAAUBCJ7kvtMFEPft7JnIuImSdBj87IDv8q21rXcqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6Aw8ub8BDi-B0C-B0gCUNbLkw5Y4YBIYABokUB48NIEgAEBigEDVVNEkgUG8FKYAawCoAH6AagBAbABALgBAsABA8gBAtABCdgBAOABAPABAIoCOnVmKCdhJywgNDk0NDcyLCAxNTE3MjY5NTM0KTt1ZigncicsIDI5NjgxMTEwLDIeAPCckgKBAiFqRHF3RUFpNjBJY0VFTmJMa3c0WUFDRGhnRWd3QURnQVFBUkl2Z2RROHViOEJGZ0FZUF9fX184UGFBQndBWGdCZ0FFQmlBRUJrQUVCbUFFQm9BRUJxQUVEc0FFQXVRRXBpNGlEQUFEZ1A4RUJLWXVJZ3dBQTREX0pBVkx3MU5mdl9lMF8yUUVBQUFBQUFBRHdQLUFCQVBVQgUPKEpnQ0FLQUNBTFVDBRAETDAJCPBUTUFDQWNnQ0FkQUNBZGdDQWVBQ0FPZ0NBUGdDQUlBREFaQURBSmdEQWFnRHV0Q0hCTG9ERVdSbFptRjFiSFFqVEVGWU1Ub3pPRFk1mgI5IS1ndndfUTYEAfCENFlCSUlBUW9BRG9SWkdWbVlYVnNkQ05NUVZneE9qTTROamsu2ALoB-ACx9MB6gJHaHR0cDovL3ByZWJpZC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9hcHBuZXh1cy10ZXN0Lmh0bWzyAhAKBkFEVl9JRBIGNCXTHPICEQoGQ1BHARM4BzE5Nzc5MzPyAhAKBUNQBRPwljg1MTM1OTSAAwGIAwGQAwCYAxSgAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMDgAQAkgQJL29wZW5ydGIymAQAogQMMjE2LjU1LjQ3Ljk0qAQAsgQMCAAQABgAIAAwADgAuAQAwAQAyAQA0gQRZGVmYXVsdCNMQVgxOjM4NjnaBAIIAeAEAPAE1suTDogFAZgFAKAF______8BA7ABqgUkYzdkY2YxNGYtZjliYS00Yzc3LWEzYjQtMjdmNmRmMzkwNjdmwAUAyQVpLhTwP9IFCQkJDFAAANgFAeAFAfAFAfoFBAgAEACQBgA.&s=f4dc8b6fa65845d08f0a87c145e12cb7d6288c2a&referrer=http%3A%2F%2Fprebid.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fappnexus-test.html&pp=${AUCTION_PRICE}"></script>',
'adid': '29681110',
'adomain': ['appnexus.com'],
'iurl': 'http://lax1-ib.adnxs.com/cr?id=2968111',
'cid': '958',
'crid': '2968111',
'dealid': 'test-dealid',
'w': 300,
'h': 250,
'ext': {
'prebid': {
'type': 'banner',
'event': {
'win': 'http://wurl.org?id=333'
},
'meta': {
'dchain': { 'ver': '1.0', 'complete': 0, 'nodes': [ { 'asi': 'magnite.com', 'bsid': '123456789', } ] }
}
},
'bidder': {
'appnexus': {
'brand_id': 1,
'auction_id': 3,
'bidder_id': 2
}
}
}
}
],
'seat': 'appnexus'
},
],
'cur': 'EUR',
'ext': {
'responsetimemillis': {
'appnexus': 8,
}
}
};
const RESPONSE_OPENRTB_VIDEO = {
id: 'c7dcf14f',
seatbid: [
{
bid: [
{
id: '1987250005171537465',
impid: 'div-gpt-ad-1460505748561-0',
price: 10,
adm: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><VAST version="3.0"><Ad id="81877115" sequence="0"><Wrapper><AdSystem version="3.0">adnxs</AdSystem><VASTAdTagURI><![CDATA[http://lax1-ib.adnxs.com/ab?e=wqT_3QLZBq]]></VASTAdTagURI><Impression><![CDATA[http://ib.adnxs.com/nop]]></Impression><Creatives><Creative adID="81877115"><Linear></Linear></Creative></Creatives></Wrapper></Ad></VAST>',
adid: '81877115',
adomain: ['appnexus.com'],
iurl: 'http://lax1-ib.adnxs.com/cr?id=81877115',
cid: '3535',
crid: '81877115',
dealid: 'test-dealid',
w: 1,
h: 1,
ext: {
prebid: {
type: 'video',
bidid: '654321'
},
bidder: {
appnexus: {
brand_id: 1,
auction_id: 6673622101799484743,
bidder_id: 2,
bid_ad_type: 1,
},
},
},
},
],
seat: 'appnexus',
},
],
ext: {
responsetimemillis: {
appnexus: 81,
},
},
};
const RESPONSE_OPENRTB_NATIVE = {
'id': 'c7dcf14f',
'seatbid': [
{
'bid': [
{
'id': '6451317310275562039',
'impid': 'div-gpt-ad-1460505748561-0',
'price': 10,
'adm': {
'ver': '1.2',
'assets': [
{
'id': 1,
'img': {
'url': 'https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg',
'w': 989,
'h': 742,
'ext': {
'appnexus': {
'prevent_crop': 0
}
}
}
},
{
'id': 2,
'img': {
'url': 'https://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png',
'w': 127,
'h': 83,
'ext': {
'appnexus': {
'prevent_crop': 0
}
}
}
},
{
'id': 0,
'title': {
'text': 'This is a Prebid Native Creative'
}
},
{
'id': 3,
'data': {
'value': 'Prebid.org'
}
}
],
'link': {
'url': 'https://lax1-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQGdce2vBWudAJZpFu1er1zA7ZzddAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAgMCAAAAALsAuhVqdgAAAAA./cpcpm=AAAAAAAAAAA=/bcr=AAAAAAAA8D8=/pp=${AUCTION_PRICE}/cnd=%213Q5HCQj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJTEFYMTo0MDc3QKcPSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAA/cca=OTMyNSNMQVgxOjQwNzc=/bn=84305/test=1/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html'
},
'eventtrackers': [
{
'event': 1,
'method': 1,
'url': 'https://lax1-ib.adnxs.com/it?an_audit=0&test=1&referrer=http%3A%2F%2Flocalhost%3A9999%2FintegrationExamples%2Fgpt%2Fdemo_native.html&e=wqT_3QKCCKACBAAAAwDWAAUBCLvO3ekFEOe47duW2NbzQBiltJba--rq6zAqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXjRkgWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQLAAQPIAQLQAQnYAQDgAQHwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NjM5MTE5OTUpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPQ0AZICnQIhb2pkaWlnajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWVAwQmFBQndBSGdBZ0FFQWlBRUFrQUVCbUFFQm9BRUJxQUVEc0FFQXVRSHpyV3FrQUFBa1FNRUI4NjFxcEFBQUpFREpBVVZpYmxDaFpRQkEyUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBUGdCQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEX1BpOENyb0RDVXhCV0RFNk5EQTNOLUFEcHctUUJBQ1lCQUhCQkFBQUFBQUFBQUFBeVFRQUFBQUFBQUFBQU5nRUFBLi6aAoUBITNRNUhDUWo4LUx3S0VMeiUhJG5QRmJJQVFvQUQRvVhBa1FEb0pURUZZTVRvME1EYzNRS2NQUxFUDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0FwHYAgDgAq2YSOoCPmh0dHA6Ly9sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9kZW1vX25hdGl2ZS5odG1sgAMAiAMBkAMAmAMUoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBA0xNzMuMjQ0LjM2LjQwqATtoySyBAwIABAAGAAgADAAOAC4BADABADIBADSBA45MzI1I0xBWDE6NDA3N9oEAggB4AQA8AS8yb4uiAUBmAUAoAX___________8BqgUkZTU5YzNlYjYtNmRkNi00MmQ5LWExMWEtM2FhMTFjOTc5MGUwwAUAyQUAAAAAAADwP9IFCQkAaVh0ANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSQk8D_IBgDaBhYKEAkQGQEBwTTgBgzyBgIIAIAHAYgHAA..&s=11ababa390e9f7983de260493fc5b91ec5b1b3d4&pp=${AUCTION_PRICE}'
}
]
},
'adid': '97494204',
'adomain': [
'http://prebid.org'
],
'iurl': 'https://lax1-ib.adnxs.com/cr?id=97494204',
'cid': '9325',
'crid': '97494204',
'cat': [
'IAB3-1'
],
'ext': {
'prebid': {
'targeting': {
'hb_bidder': 'appnexus',
'hb_pb': '10.00'
},
'type': 'native',
'video': {
'duration': 0,
'primary_category': ''
}
},
'bidder': {
'appnexus': {
'brand_id': 555545,
'auction_id': 4676806524825984103,
'bidder_id': 2,
'bid_ad_type': 3
}
}
}
}
],
'seat': 'appnexus'
}
]
};
describe('S2S Adapter', function () {
let adapter,
addBidResponse = sinon.spy(),
done = sinon.spy();
beforeEach(function () {
config.resetConfig();
adapter = new Adapter();
BID_REQUESTS = [
{
'bidderCode': 'appnexus',
'auctionId': '173afb6d132ba3',
'bidderRequestId': '3d1063078dfcc8',
'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5',
'bids': [
{
'bidder': 'appnexus',
'params': {
'placementId': '10433394',
'member': 123,
'keywords': {
'foo': ['bar', 'baz'],
'fizz': ['buzz']
}
},
'bid_id': '123',
'adUnitCode': 'div-gpt-ad-1460505748561-0',
'mediaTypes': {
'banner': {
'sizes': [[300, 250]]
}
},
'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c',
'sizes': [300, 250],
'bidId': '123',
'bidderRequestId': '3d1063078dfcc8',
'auctionId': '173afb6d132ba3',
'storedAuctionResponse': 11111
}
],
'auctionStart': 1510852447530,
'timeout': 5000,
'src': 's2s',
'doneCbCallCount': 0,
'refererInfo': {
'referer': 'http://mytestpage.com'
}
}
];
});
afterEach(function () {
addBidResponse.resetHistory();
done.resetHistory();
});
after(function () {
config.resetConfig();
});
describe('request function', function () {
beforeEach(function () {
resetSyncedStatus();
});
it('should block request if config did not define p1Consent URL in endpoint object config', function() {
let badConfig = utils.deepClone(CONFIG);
badConfig.endpoint = { noP1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' };
config.setConfig({ s2sConfig: badConfig });
let badCfgRequest = utils.deepClone(REQUEST);
badCfgRequest.s2sConfig = badConfig;
adapter.callBids(badCfgRequest, BID_REQUESTS, addBidResponse, done, ajax);
expect(server.requests.length).to.equal(0);
});
it('should block request if config did not define noP1Consent URL in endpoint object config', function() {
let badConfig = utils.deepClone(CONFIG);
badConfig.endpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' };
config.setConfig({ s2sConfig: badConfig });
let badCfgRequest = utils.deepClone(REQUEST);
badCfgRequest.s2sConfig = badConfig;
let badBidderRequest = utils.deepClone(BID_REQUESTS);
badBidderRequest[0].gdprConsent = {
consentString: 'abc123',
addtlConsent: 'superduperconsent',
gdprApplies: true,
apiVersion: 2,
vendorData: {
purpose: {
consents: {
1: false
}
}
}
};
adapter.callBids(badCfgRequest, badBidderRequest, addBidResponse, done, ajax);
expect(server.requests.length).to.equal(0);
});
it('should block request if config did not define any URLs in endpoint object config', function() {
let badConfig = utils.deepClone(CONFIG);
badConfig.endpoint = {};
config.setConfig({ s2sConfig: badConfig });
let badCfgRequest = utils.deepClone(REQUEST);
badCfgRequest.s2sConfig = badConfig;
adapter.callBids(badCfgRequest, BID_REQUESTS, addBidResponse, done, ajax);
expect(server.requests.length).to.equal(0);
});
it('should add outstream bc renderer exists on mediatype', function () {
config.setConfig({ s2sConfig: CONFIG });
adapter.callBids(OUTSTREAM_VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.imp[0].banner).to.exist;
expect(requestBid.imp[0].video).to.exist;
});
it('should default video placement if not defined and instream', function () {
let ortb2Config = utils.deepClone(CONFIG);
ortb2Config.endpoint.p1Consent = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction';
config.setConfig({ s2sConfig: ortb2Config });
let videoBid = utils.deepClone(VIDEO_REQUEST);
videoBid.ad_units[0].mediaTypes.video.context = 'instream';
adapter.callBids(videoBid, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.imp[0].banner).to.not.exist;
expect(requestBid.imp[0].video).to.exist;
expect(requestBid.imp[0].video.placement).to.equal(1);
});
it('converts video mediaType properties into openRTB format', function () {
let ortb2Config = utils.deepClone(CONFIG);
ortb2Config.endpoint.p1Consent = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction';
config.setConfig({ s2sConfig: ortb2Config });
let videoBid = utils.deepClone(VIDEO_REQUEST);
videoBid.ad_units[0].mediaTypes.video.context = 'instream';
adapter.callBids(videoBid, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.imp[0].banner).to.not.exist;
expect(requestBid.imp[0].video).to.exist;
expect(requestBid.imp[0].video.placement).to.equal(1);
expect(requestBid.imp[0].video.w).to.equal(640);
expect(requestBid.imp[0].video.h).to.equal(480);
expect(requestBid.imp[0].video.playerSize).to.be.undefined;
expect(requestBid.imp[0].video.context).to.be.undefined;
});
it('exists and is a function', function () {
expect(adapter.callBids).to.exist.and.to.be.a('function');
});
describe('gdpr tests', function () {
afterEach(function () {
$$PREBID_GLOBAL$$.requestBids.removeAll();
});
it('adds gdpr consent information to ortb2 request depending on presence of module', function () {
let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: CONFIG };
config.setConfig(consentConfig);
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
gdprBidRequest[0].gdprConsent = {
consentString: 'abc123',
gdprApplies: true
};
adapter.callBids(REQUEST, gdprBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.regs.ext.gdpr).is.equal(1);
expect(requestBid.user.ext.consent).is.equal('abc123');
config.resetConfig();
config.setConfig({ s2sConfig: CONFIG });
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
requestBid = JSON.parse(server.requests[1].requestBody);
expect(requestBid.regs).to.not.exist;
expect(requestBid.user).to.not.exist;
});
it('adds additional consent information to ortb2 request depending on presence of module', function () {
let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: CONFIG };
config.setConfig(consentConfig);
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
gdprBidRequest[0].gdprConsent = {
consentString: 'abc123',
addtlConsent: 'superduperconsent',
gdprApplies: true
};
adapter.callBids(REQUEST, gdprBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.regs.ext.gdpr).is.equal(1);
expect(requestBid.user.ext.consent).is.equal('abc123');
expect(requestBid.user.ext.ConsentedProvidersSettings.consented_providers).is.equal('superduperconsent');
config.resetConfig();
config.setConfig({ s2sConfig: CONFIG });
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
requestBid = JSON.parse(server.requests[1].requestBody);
expect(requestBid.regs).to.not.exist;
expect(requestBid.user).to.not.exist;
});
it('check gdpr info gets added into cookie_sync request: have consent data', function () {
let cookieSyncConfig = utils.deepClone(CONFIG);
cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' };
let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: cookieSyncConfig };
config.setConfig(consentConfig);
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
gdprBidRequest[0].gdprConsent = {
consentString: 'abc123def',
gdprApplies: true
};
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
adapter.callBids(s2sBidRequest, gdprBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.gdpr).is.equal(1);
expect(requestBid.gdpr_consent).is.equal('abc123def');
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
});
it('check gdpr info gets added into cookie_sync request: have consent data but gdprApplies is false', function () {
let cookieSyncConfig = utils.deepClone(CONFIG);
cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' };
let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: cookieSyncConfig };
config.setConfig(consentConfig);
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
gdprBidRequest[0].gdprConsent = {
consentString: 'xyz789abcc',
gdprApplies: false
};
adapter.callBids(s2sBidRequest, gdprBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.gdpr).is.equal(0);
expect(requestBid.gdpr_consent).is.undefined;
});
it('checks gdpr info gets added to cookie_sync request: applies is false', function () {
let cookieSyncConfig = utils.deepClone(CONFIG);
cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' };
let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: cookieSyncConfig };
config.setConfig(consentConfig);
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
gdprBidRequest[0].gdprConsent = {
consentString: undefined,
gdprApplies: false
};
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
adapter.callBids(s2sBidRequest, gdprBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.gdpr).is.equal(0);
expect(requestBid.gdpr_consent).is.undefined;
});
});
describe('us_privacy (ccpa) consent data', function () {
afterEach(function () {
$$PREBID_GLOBAL$$.requestBids.removeAll();
});
it('is added to ortb2 request when in bidRequest', function () {
config.setConfig({ s2sConfig: CONFIG });
let uspBidRequest = utils.deepClone(BID_REQUESTS);
uspBidRequest[0].uspConsent = '1NYN';
adapter.callBids(REQUEST, uspBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.regs.ext.us_privacy).is.equal('1NYN');
config.resetConfig();
config.setConfig({ s2sConfig: CONFIG });
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
requestBid = JSON.parse(server.requests[1].requestBody);
expect(requestBid.regs).to.not.exist;
});
it('is added to cookie_sync request when in bidRequest', function () {
let cookieSyncConfig = utils.deepClone(CONFIG);
cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' };
config.setConfig({ s2sConfig: cookieSyncConfig });
let uspBidRequest = utils.deepClone(BID_REQUESTS);
uspBidRequest[0].uspConsent = '1YNN';
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
adapter.callBids(s2sBidRequest, uspBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.us_privacy).is.equal('1YNN');
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
});
});
describe('gdpr and us_privacy (ccpa) consent data', function () {
afterEach(function () {
$$PREBID_GLOBAL$$.requestBids.removeAll();
});
it('is added to ortb2 request when in bidRequest', function () {
config.setConfig({ s2sConfig: CONFIG });
let consentBidRequest = utils.deepClone(BID_REQUESTS);
consentBidRequest[0].uspConsent = '1NYN';
consentBidRequest[0].gdprConsent = {
consentString: 'abc123',
gdprApplies: true
};
adapter.callBids(REQUEST, consentBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.regs.ext.us_privacy).is.equal('1NYN');
expect(requestBid.regs.ext.gdpr).is.equal(1);
expect(requestBid.user.ext.consent).is.equal('abc123');
config.resetConfig();
config.setConfig({ s2sConfig: CONFIG });
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
requestBid = JSON.parse(server.requests[1].requestBody);
expect(requestBid.regs).to.not.exist;
expect(requestBid.user).to.not.exist;
});
it('is added to cookie_sync request when in bidRequest', function () {
let cookieSyncConfig = utils.deepClone(CONFIG);
cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' };
config.setConfig({ s2sConfig: cookieSyncConfig });
let consentBidRequest = utils.deepClone(BID_REQUESTS);
consentBidRequest[0].uspConsent = '1YNN';
consentBidRequest[0].gdprConsent = {
consentString: 'abc123def',
gdprApplies: true
};
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig
adapter.callBids(s2sBidRequest, consentBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.us_privacy).is.equal('1YNN');
expect(requestBid.gdpr).is.equal(1);
expect(requestBid.gdpr_consent).is.equal('abc123def');
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
});
});
it('adds device and app objects to request', function () {
const _config = {
s2sConfig: CONFIG,
device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' },
app: { bundle: 'com.test.app' },
};
config.setConfig(_config);
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.device).to.deep.equal({
ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC',
w: window.innerWidth,
h: window.innerHeight
});
expect(requestBid.app).to.deep.equal({
bundle: 'com.test.app',
publisher: { 'id': '1' }
});
});
it('adds device and app objects to request for OpenRTB', function () {
const s2sConfig = Object.assign({}, CONFIG, {
endpoint: {
p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
}
});
const _config = {
s2sConfig: s2sConfig,
device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' },
app: { bundle: 'com.test.app' },
};
config.setConfig(_config);
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.device).to.deep.equal({
ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC',
w: window.innerWidth,
h: window.innerHeight
});
expect(requestBid.app).to.deep.equal({
bundle: 'com.test.app',
publisher: { 'id': '1' }
});
});
it('adds debugging value from storedAuctionResponse to OpenRTB', function () {
const _config = {
s2sConfig: CONFIG,
device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' },
app: { bundle: 'com.test.app' }
};
config.setConfig(_config);
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.imp).to.exist.and.to.be.a('array');
expect(requestBid.imp).to.have.lengthOf(1);
expect(requestBid.imp[0].ext).to.exist.and.to.be.a('object');
expect(requestBid.imp[0].ext.prebid).to.exist.and.to.be.a('object');
expect(requestBid.imp[0].ext.prebid.storedauctionresponse).to.exist.and.to.be.a('object');
expect(requestBid.imp[0].ext.prebid.storedauctionresponse.id).to.equal('11111');
});
describe('price floors module', function () {
function runTest(expectedFloor, expectedCur) {
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[requestCount].requestBody);
expect(requestBid.imp[0].bidfloor).to.equal(expectedFloor);
expect(requestBid.imp[0].bidfloorcur).to.equal(expectedCur);
requestCount += 1;
}
let getFloorResponse, requestCount;
beforeEach(function () {
getFloorResponse = {};
requestCount = 0;
});
it('should NOT pass bidfloor and bidfloorcur when getFloor not present or returns invalid response', function () {
const _config = {
s2sConfig: CONFIG,
};
config.setConfig(_config);
// if no get floor
runTest(undefined, undefined);
// if getFloor returns empty object
BID_REQUESTS[0].bids[0].getFloor = () => getFloorResponse;
sinon.spy(BID_REQUESTS[0].bids[0], 'getFloor');
runTest(undefined, undefined);
// make sure getFloor was called
expect(
BID_REQUESTS[0].bids[0].getFloor.calledWith({
currency: 'USD',
})
).to.be.true;
// if getFloor does not return number
getFloorResponse = {currency: 'EUR', floor: 'not a number'};
runTest(undefined, undefined);
// if getFloor does not return currency
getFloorResponse = {floor: 1.1};
runTest(undefined, undefined);
});
it('should correctly pass bidfloor and bidfloorcur', function () {
const _config = {
s2sConfig: CONFIG,
};
config.setConfig(_config);
BID_REQUESTS[0].bids[0].getFloor = () => getFloorResponse;
sinon.spy(BID_REQUESTS[0].bids[0], 'getFloor');
// returns USD and string floor
getFloorResponse = {currency: 'USD', floor: '1.23'};
runTest(1.23, 'USD');
// make sure getFloor was called
expect(
BID_REQUESTS[0].bids[0].getFloor.calledWith({
currency: 'USD',
})
).to.be.true;
// returns non USD and number floor
getFloorResponse = {currency: 'EUR', floor: 0.85};
runTest(0.85, 'EUR');
});
it('should correctly pass adServerCurrency when set to getFloor not default', function () {
config.setConfig({
s2sConfig: CONFIG,
currency: { adServerCurrency: 'JPY' },
});
// we have to start requestCount at 1 because a conversion rates fetch occurs when adServerCur is not USD!
requestCount = 1;
BID_REQUESTS[0].bids[0].getFloor = () => getFloorResponse;
sinon.spy(BID_REQUESTS[0].bids[0], 'getFloor');
// returns USD and string floor
getFloorResponse = {currency: 'JPY', floor: 97.2};
runTest(97.2, 'JPY');
// make sure getFloor was called with JPY
expect(
BID_REQUESTS[0].bids[0].getFloor.calledWith({
currency: 'JPY',
})
).to.be.true;
});
});
it('adds device.w and device.h even if the config lacks a device object', function () {
const _config = {
s2sConfig: CONFIG,
app: { bundle: 'com.test.app' },
};
config.setConfig(_config);
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.device).to.deep.equal({
w: window.innerWidth,
h: window.innerHeight
});
expect(requestBid.app).to.deep.equal({
bundle: 'com.test.app',
publisher: { 'id': '1' }
});
});
it('adds native request for OpenRTB', function () {
const _config = {
s2sConfig: CONFIG
};
config.setConfig(_config);
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.imp[0].native).to.deep.equal({
request: JSON.stringify({
'context': 1,
'plcmttype': 1,
'eventtrackers': [{
event: 1,
methods: [1]
}],
'assets': [
{
'required': 1,
'title': {
'len': 800
}
},
{
'required': 1,
'img': {
'type': 3,
'w': 989,
'h': 742
}
},
{
'required': 1,
'img': {
'type': 1,
'wmin': 10,
'hmin': 10,
'ext': {
'aspectratios': ['1:1']
}
}
},
{
'required': 1,
'data': {
'type': 1
}
}
]
}),
ver: '1.2'
});
});
it('adds site if app is not present', function () {
const _config = {
s2sConfig: CONFIG,
site: {
publisher: {
id: '1234',
domain: 'test.com'
},
content: {
language: 'en'
}
}
};
config.setConfig(_config);
adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.site).to.exist.and.to.be.a('object');
expect(requestBid.site.publisher).to.exist.and.to.be.a('object');
expect(requestBid.site.publisher.id).to.exist.and.to.be.a('string');
expect(requestBid.site.publisher.domain).to.exist.and.to.be.a('string');
expect(requestBid.site.page).to.exist.and.to.be.a('string');
expect(requestBid.site.content).to.exist.and.to.be.a('object');
expect(requestBid.site.content.language).to.exist.and.to.be.a('string');
expect(requestBid.site).to.deep.equal({
publisher: {
id: '1234',
domain: 'test.com'
},
content: {
language: 'en'
},
page: 'http://mytestpage.com'
});
});
it('adds appnexus aliases to request', function () {
config.setConfig({ s2sConfig: CONFIG });
const aliasBidder = {
bidder: 'brealtime',
params: { placementId: '123456' }
};
const request = utils.deepClone(REQUEST);
request.ad_units[0].bids = [aliasBidder];
adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.ext).to.haveOwnProperty('prebid');
expect(requestBid.ext.prebid).to.deep.include({
aliases: {
brealtime: 'appnexus'
},
auctiontimestamp: 1510852447530,
targeting: {
includebidderkeys: false,
includewinners: true
}
});
});
it('adds dynamic aliases to request', function () {
config.setConfig({ s2sConfig: CONFIG });
const alias = 'foobar';
const aliasBidder = {
bidder: alias,
params: { placementId: '123456' }
};
const request = utils.deepClone(REQUEST);
request.ad_units[0].bids = [aliasBidder];
// TODO: stub this
$$PREBID_GLOBAL$$.aliasBidder('appnexus', alias);
adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.ext).to.haveOwnProperty('prebid');
expect(requestBid.ext.prebid).to.deep.include({
aliases: {
[alias]: 'appnexus'
},
auctiontimestamp: 1510852447530,
targeting: {
includebidderkeys: false,
includewinners: true
}
});
});
it('skips pbs alias when skipPbsAliasing is enabled in adapter', function() {
const s2sConfig = Object.assign({}, CONFIG, {
endpoint: {
p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
}
});
config.setConfig({ s2sConfig: s2sConfig });
const aliasBidder = {
bidder: 'mediafuse',
params: { aid: 123 }
};
const request = utils.deepClone(REQUEST);
request.ad_units[0].bids = [aliasBidder];
adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.ext).to.deep.equal({
prebid: {
auctiontimestamp: 1510852447530,
targeting: {
includebidderkeys: false,
includewinners: true
},
channel: {
name: 'pbjs',
version: 'v$prebid.version$'
}
}
});
});
it('skips dynamic aliases to request when skipPbsAliasing enabled', function () {
const s2sConfig = Object.assign({}, CONFIG, {
endpoint: {
p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
}
});
config.setConfig({ s2sConfig: s2sConfig });
const alias = 'foobar_1';
const aliasBidder = {
bidder: alias,
params: { aid: 123456 }
};
const request = utils.deepClone(REQUEST);
request.ad_units[0].bids = [aliasBidder];
// TODO: stub this
$$PREBID_GLOBAL$$.aliasBidder('appnexus', alias, { skipPbsAliasing: true });
adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.ext).to.deep.equal({
prebid: {
auctiontimestamp: 1510852447530,
targeting: {
includebidderkeys: false,
includewinners: true
},
channel: {
name: 'pbjs',
version: 'v$prebid.version$'
}
}
});
});
it('converts appnexus params to expected format for PBS', function () {
const s2sConfig = Object.assign({}, CONFIG, {
endpoint: {
p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'
}
});
config.setConfig({ s2sConfig: s2sConfig });
const myRequest = utils.deepClone(REQUEST);
myRequest.ad_units[0].bids[0].params.usePaymentRule = true;
myRequest.ad_units[0].bids[0].params.keywords = {
foo: ['bar', 'baz'],
fizz: ['buzz']
};
adapter.callBids(myRequest, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.imp[0].ext.appnexus).to.exist;
expect(requestBid.imp[0].ext.appnexus.placement_id).to.exist.and.to.equal(10433394);
expect(requestBid.imp[0].ext.appnexus.use_pmt_rule).to.exist.and.to.be.true;
expect(requestBid.imp[0].ext.appnexus.member).to.exist;
expect(requestBid.imp[0].ext.appnexus.keywords).to.exist.and.to.deep.equal([{
key: 'foo',
value: ['bar', 'baz']
}, {
key: 'fizz',
value: ['buzz']
}]);
});
it('adds limit to the cookie_sync request if userSyncLimit is greater than 0', function () {
let cookieSyncConfig = utils.deepClone(CONFIG);
cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' };
cookieSyncConfig.userSyncLimit = 1;
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
config.setConfig({ s2sConfig: cookieSyncConfig });
let bidRequest = utils.deepClone(BID_REQUESTS);
adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
expect(requestBid.limit).is.equal(1);
});
it('does not add limit to cooke_sync request if userSyncLimit is missing or 0', function () {
let cookieSyncConfig = utils.deepClone(CONFIG);
cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' };
config.setConfig({ s2sConfig: cookieSyncConfig });
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
let bidRequest = utils.deepClone(BID_REQUESTS);
adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
expect(requestBid.limit).is.undefined;
cookieSyncConfig.userSyncLimit = 0;
config.resetConfig();
config.setConfig({ s2sConfig: cookieSyncConfig });
const s2sBidRequest2 = utils.deepClone(REQUEST);
s2sBidRequest2.s2sConfig = cookieSyncConfig;
bidRequest = utils.deepClone(BID_REQUESTS);
adapter.callBids(s2sBidRequest2, bidRequest, addBidResponse, done, ajax);
requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
expect(requestBid.limit).is.undefined;
});
it('adds s2sConfig adapterOptions to request for ORTB', function () {
const s2sConfig = Object.assign({}, CONFIG, {
adapterOptions: {
appnexus: {
key: 'value'
}
}
});
const _config = {
s2sConfig: s2sConfig,
device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' },
app: { bundle: 'com.test.app' },
};
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = s2sConfig;
config.setConfig(_config);
adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.imp[0].ext.appnexus).to.haveOwnProperty('key');
expect(requestBid.imp[0].ext.appnexus.key).to.be.equal('value')
});
describe('config site value is added to the oRTB request', function () {
const s2sConfig = Object.assign({}, CONFIG, {
adapterOptions: {
appnexus: {
key: 'value'
}
}
});
const device = {
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
ip: '75.97.0.47'
};
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = s2sConfig;
it('and overrides publisher and page', function () {
config.setConfig({
s2sConfig: s2sConfig,
site: {
domain: 'nytimes.com',
page: 'http://www.nytimes.com',
publisher: { id: '2' }
},
device: device
});
adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax);
const requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.site).to.exist.and.to.be.a('object');
expect(requestBid.site.domain).to.equal('nytimes.com');
expect(requestBid.site.page).to.equal('http://www.nytimes.com');
expect(requestBid.site.publisher).to.exist.and.to.be.a('object');
expect(requestBid.site.publisher.id).to.equal('2');
});
it('and merges domain and page with the config site value', function () {
config.setConfig({
s2sConfig: s2sConfig,
site: {
foo: 'bar'
},