',
+ 'crid': '540221061',
+ 'w': 970,
+ 'h': 250,
+ 'ext': {
+ 'prebid': {
+ 'type': 'banner'
+ },
+ 'bidder': {
+ 'newspassid': {}
+ }
+ },
+ 'cpm': 0.01,
+ 'bidId': '3025f169863b7f8',
+ 'requestId': '3025f169863b7f8',
+ 'width': 970,
+ 'height': 250,
+ 'ad': '
',
+ 'netRevenue': true,
+ 'creativeId': '540221061',
+ 'currency': 'USD',
+ 'ttl': 300,
+ 'originalCpm': 0.01,
+ 'originalCurrency': 'USD'
+ }
+ ],
+ 'seat': 'openx'
+ }
+ ],
+ 'ext': {
+ 'debug': {},
+ 'responsetimemillis': {
+ 'beeswax': 6,
+ 'openx': 91,
+ 'npappnexus': 40,
+ 'npbeeswax': 6
+ }
+ }
+ },
+ 'headers': {}
+};
+describe('newspassid Adapter', function () {
+ describe('isBidRequestValid', function () {
+ let validBidReq = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1310000099',
+ publisherId: '9876abcd12-3',
+ siteId: '1234567890'
+ }
+ };
+ it('should return true when required params found', function () {
+ expect(spec.isBidRequestValid(validBidReq)).to.equal(true);
+ });
+ var validBidReq2 = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1310000099',
+ publisherId: '9876abcd12-3',
+ siteId: '1234567890',
+ customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}]
+ },
+ siteId: 1234567890
+ }
+ it('should return true when required params found and all optional params are valid', function () {
+ expect(spec.isBidRequestValid(validBidReq2)).to.equal(true);
+ });
+ var xEmptyPlacement = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '',
+ publisherId: '9876abcd12-3',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate empty placementId', function () {
+ expect(spec.isBidRequestValid(xEmptyPlacement)).to.equal(false);
+ });
+ var xMissingPlacement = {
+ bidder: BIDDER_CODE,
+ params: {
+ publisherId: '9876abcd12-3',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate missing placementId', function () {
+ expect(spec.isBidRequestValid(xMissingPlacement)).to.equal(false);
+ });
+ var xBadPlacement = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '123X45',
+ publisherId: '9876abcd12-3',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate placementId with a non-numeric value', function () {
+ expect(spec.isBidRequestValid(xBadPlacement)).to.equal(false);
+ });
+ var xBadPlacementTooShort = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: 123456789, /* should be exactly 10 chars */
+ publisherId: '9876abcd12-3',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate placementId with a numeric value of wrong length', function () {
+ expect(spec.isBidRequestValid(xBadPlacementTooShort)).to.equal(false);
+ });
+ var xBadPlacementTooLong = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: 12345678901, /* should be exactly 10 chars */
+ publisherId: '9876abcd12-3',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate placementId with a numeric value of wrong length', function () {
+ expect(spec.isBidRequestValid(xBadPlacementTooLong)).to.equal(false);
+ });
+ var xMissingPublisher = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1234567890',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate missing publisherId', function () {
+ expect(spec.isBidRequestValid(xMissingPublisher)).to.equal(false);
+ });
+ var xMissingSiteId = {
+ bidder: BIDDER_CODE,
+ params: {
+ publisherId: '9876abcd12-3',
+ placementId: '1234567890',
+ }
+ };
+ it('should not validate missing sitetId', function () {
+ expect(spec.isBidRequestValid(xMissingSiteId)).to.equal(false);
+ });
+ var xBadPublisherTooShort = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1234567890',
+ publisherId: '9876abcd12a',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate publisherId being too short', function () {
+ expect(spec.isBidRequestValid(xBadPublisherTooShort)).to.equal(false);
+ });
+ var xBadPublisherTooLong = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1234567890',
+ publisherId: '9876abcd12abc',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate publisherId being too long', function () {
+ expect(spec.isBidRequestValid(xBadPublisherTooLong)).to.equal(false);
+ });
+ var publisherNumericOk = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1234567890',
+ publisherId: 123456789012,
+ siteId: '1234567890'
+ }
+ };
+ it('should validate publisherId being 12 digits', function () {
+ expect(spec.isBidRequestValid(publisherNumericOk)).to.equal(true);
+ });
+ var xEmptyPublisher = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1234567890',
+ publisherId: '',
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate empty publisherId', function () {
+ expect(spec.isBidRequestValid(xEmptyPublisher)).to.equal(false);
+ });
+ var xBadSite = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: '1234567890',
+ publisherId: '9876abcd12-3',
+ siteId: '12345Z'
+ }
+ };
+ it('should not validate bad siteId', function () {
+ expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
+ });
+ it('should not validate siteId too long', function () {
+ expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
+ });
+ it('should not validate siteId too short', function () {
+ expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
+ });
+ var allNonStrings = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: 1234567890,
+ publisherId: '9876abcd12-3',
+ siteId: 1234567890
+ }
+ };
+ it('should validate all numeric values being sent as non-string numbers', function () {
+ expect(spec.isBidRequestValid(allNonStrings)).to.equal(true);
+ });
+ var emptySiteId = {
+ bidder: BIDDER_CODE,
+ params: {
+ placementId: 1234567890,
+ publisherId: '9876abcd12-3',
+ siteId: ''
+ }
+ };
+ it('should not validate siteId being empty string (it is required now)', function () {
+ expect(spec.isBidRequestValid(emptySiteId)).to.equal(false);
+ });
+ var xBadCustomData = {
+ bidder: BIDDER_CODE,
+ params: {
+ 'placementId': '1234567890',
+ 'publisherId': '9876abcd12-3',
+ 'siteId': '1234567890',
+ 'customData': 'this aint gonna work'
+ }
+ };
+ it('should not validate customData not being an array', function () {
+ expect(spec.isBidRequestValid(xBadCustomData)).to.equal(false);
+ });
+ var xBadCustomDataOldCustomdataValue = {
+ bidder: BIDDER_CODE,
+ params: {
+ 'placementId': '1234567890',
+ 'publisherId': '9876abcd12-3',
+ 'siteId': '1234567890',
+ 'customData': {'gender': 'bart', 'age': 'low'}
+ }
+ };
+ it('should not validate customData being an object, not an array', function () {
+ expect(spec.isBidRequestValid(xBadCustomDataOldCustomdataValue)).to.equal(false);
+ });
+ var xBadCustomDataZerocd = {
+ bidder: BIDDER_CODE,
+ params: {
+ 'placementId': '1111111110',
+ 'publisherId': '9876abcd12-3',
+ 'siteId': '1234567890',
+ 'customData': []
+ }
+ };
+ it('should not validate customData array having no elements', function () {
+ expect(spec.isBidRequestValid(xBadCustomDataZerocd)).to.equal(false);
+ });
+ var xBadCustomDataNotargeting = {
+ bidder: BIDDER_CODE,
+ params: {
+ 'placementId': '1234567890',
+ 'publisherId': '9876abcd12-3',
+ 'customData': [{'settings': {}, 'xx': {'gender': 'bart', 'age': 'low'}}],
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate customData[] having no "targeting"', function () {
+ expect(spec.isBidRequestValid(xBadCustomDataNotargeting)).to.equal(false);
+ });
+ var xBadCustomDataTgtNotObj = {
+ bidder: BIDDER_CODE,
+ params: {
+ 'placementId': '1234567890',
+ 'publisherId': '9876abcd12-3',
+ 'customData': [{'settings': {}, 'targeting': 'this should be an object'}],
+ siteId: '1234567890'
+ }
+ };
+ it('should not validate customData[0].targeting not being an object', function () {
+ expect(spec.isBidRequestValid(xBadCustomDataTgtNotObj)).to.equal(false);
+ });
+ var xBadCustomParams = {
+ bidder: BIDDER_CODE,
+ params: {
+ 'placementId': '1234567890',
+ 'publisherId': '9876abcd12-3',
+ 'siteId': '1234567890',
+ 'customParams': 'this key is no longer valid'
+ }
+ };
+ it('should not validate customParams - this is a renamed key', function () {
+ expect(spec.isBidRequestValid(xBadCustomParams)).to.equal(false);
+ });
+ });
+ describe('buildRequests', function () {
+ it('sends bid request to NEWSPASSURI via POST', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ expect(request.url).to.equal(NEWSPASSURI);
+ expect(request.method).to.equal('POST');
+ });
+ it('sends data as a string', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ expect(request.data).to.be.a('string');
+ });
+ it('sends all bid parameters', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
+ });
+ it('adds all parameters inside the ext object only', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ expect(request.data).to.be.a('string');
+ var data = JSON.parse(request.data);
+ expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
+ expect(request).not.to.have.key('lotameData');
+ expect(request).not.to.have.key('customData');
+ });
+ it('adds all parameters inside the ext object only - lightning', function () {
+ let localBidReq = JSON.parse(JSON.stringify(validBidRequests));
+ const request = spec.buildRequests(localBidReq, validBidderRequest);
+ expect(request.data).to.be.a('string');
+ var data = JSON.parse(request.data);
+ expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
+ expect(request).not.to.have.key('lotameData');
+ expect(request).not.to.have.key('customData');
+ });
+ it('has correct bidder', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ expect(request.bidderRequest.bids[0].bidder).to.equal(BIDDER_CODE);
+ });
+ it('handles mediaTypes element correctly', function () {
+ const request = spec.buildRequests(validBidRequestsWithBannerMediaType, validBidderRequest);
+ expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
+ });
+ it('handles no newspassid or custom data', function () {
+ const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest);
+ expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
+ });
+ it('should not crash when there is no sizes element at all', function () {
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
+ expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
+ });
+ it('should be able to handle non-single requests', function () {
+ config.setConfig({'newspassid': {'singleRequest': false}});
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
+ expect(request).to.be.a('array');
+ expect(request[0]).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
+ config.setConfig({'newspassid': {'singleRequest': true}});
+ });
+ it('should not have imp[N].ext.newspassid.userId', function () {
+ let bidderRequest = validBidderRequest;
+ let bidRequests = validBidRequests;
+ bidRequests[0]['userId'] = {
+ 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}},
+ 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } },
+ 'idl_env': '3333',
+ 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue',
+ 'pubcid': '5555',
+ 'tdid': '6666',
+ 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'}
+ };
+ bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids'];
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ const payload = JSON.parse(request.data);
+ let firstBid = payload.imp[0].ext.newspassid;
+ expect(firstBid).to.not.have.property('userId');
+ delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests
+ });
+ it('should pick up the value of pubcid when built using the pubCommonId module (not userId)', function () {
+ let bidRequests = validBidRequests;
+ bidRequests[0]['userId'] = {
+ 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}},
+ 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } },
+ 'idl_env': '3333',
+ 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue',
+ 'tdid': '6666',
+ 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'}
+ };
+ bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids'];
+ const request = spec.buildRequests(bidRequests, validBidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.ext.newspassid.pubcid).to.equal(bidRequests[0]['crumbs']['pubcid']);
+ delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests
+ });
+ it('should add a user.ext.eids object to contain user ID data in the new location (Nov 2019) Updated Aug 2020', function() {
+ const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.user).to.exist;
+ expect(payload.user.ext).to.exist;
+ expect(payload.user.ext.eids).to.exist;
+ expect(payload.user.ext.eids[0]['source']).to.equal('pubcid.org');
+ expect(payload.user.ext.eids[0]['uids'][0]['id']).to.equal('12345678');
+ expect(payload.user.ext.eids[1]['source']).to.equal('adserver.org');
+ expect(payload.user.ext.eids[1]['uids'][0]['id']).to.equal('1111tdid');
+ expect(payload.user.ext.eids[2]['source']).to.equal('id5-sync.com');
+ expect(payload.user.ext.eids[2]['uids'][0]['id']).to.equal('ID5-someId');
+ expect(payload.user.ext.eids[3]['source']).to.equal('criteoId');
+ expect(payload.user.ext.eids[3]['uids'][0]['id']).to.equal('1111criteoId');
+ expect(payload.user.ext.eids[4]['source']).to.equal('idl_env');
+ expect(payload.user.ext.eids[4]['uids'][0]['id']).to.equal('liverampId');
+ expect(payload.user.ext.eids[5]['source']).to.equal('lipb');
+ expect(payload.user.ext.eids[5]['uids'][0]['id']['lipbid']).to.equal('lipbidId123');
+ expect(payload.user.ext.eids[6]['source']).to.equal('parrableId');
+ expect(payload.user.ext.eids[6]['uids'][0]['id']['eid']).to.equal('01.5678.parrableid');
+ });
+ it('replaces the auction url for a config override', function () {
+ spec.propertyBag.config = null;
+ let fakeOrigin = 'http://sometestendpoint';
+ config.setConfig({'newspassid': {'endpointOverride': {'origin': fakeOrigin}}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ expect(request.url).to.equal(fakeOrigin + '/openrtb2/auction');
+ expect(request.method).to.equal('POST');
+ const data = JSON.parse(request.data);
+ expect(data.ext.newspassid.origin).to.equal(fakeOrigin);
+ config.setConfig({'newspassid': {'kvpPrefix': null, 'endpointOverride': null}});
+ });
+ it('replaces the FULL auction url for a config override', function () {
+ spec.propertyBag.config = null;
+ let fakeurl = 'http://sometestendpoint/myfullurl';
+ config.setConfig({'newspassid': {'endpointOverride': {'auctionUrl': fakeurl}}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ expect(request.url).to.equal(fakeurl);
+ expect(request.method).to.equal('POST');
+ const data = JSON.parse(request.data);
+ expect(data.ext.newspassid.origin).to.equal(fakeurl);
+ config.setConfig({'newspassid': {'kvpPrefix': null, 'endpointOverride': null}});
+ });
+ it('should ignore kvpPrefix', function () {
+ spec.propertyBag.config = null;
+ config.setConfig({'newspassid': {'kvpPrefix': 'np'}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(result[0].adserverTargeting).to.have.own.property('np_appnexus_crid');
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_crid')).to.equal('98493581');
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_adId')).to.equal('2899ec066a91ff8-0-np-0');
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_size')).to.equal('300x600');
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_pb_r')).to.equal('0.50');
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_bid')).to.equal('true');
+ config.resetConfig();
+ });
+ it('should create a meta object on each bid returned', function () {
+ spec.propertyBag.config = null;
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(result[0]).to.have.own.property('meta');
+ expect(result[0].meta.advertiserDomains[0]).to.equal('http://prebid.org');
+ config.resetConfig();
+ });
+ it('should use nptestmode GET value if set', function() {
+ var specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {'nptestmode': 'mytestvalue_123'};
+ };
+ const request = specMock.buildRequests(validBidRequests, validBidderRequest);
+ const data = JSON.parse(request.data);
+ expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
+ expect(data.imp[0].ext.newspassid.customData[0].targeting.nptestmode).to.equal('mytestvalue_123');
+ });
+ it('should pass through GET params if present: npf, nppf, nprp, npip', function() {
+ var specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {npf: '1', nppf: '0', nprp: '2', npip: '123'};
+ };
+ const request = specMock.buildRequests(validBidRequests, validBidderRequest);
+ const data = JSON.parse(request.data);
+ expect(data.ext.newspassid.npf).to.equal(1);
+ expect(data.ext.newspassid.nppf).to.equal(0);
+ expect(data.ext.newspassid.nprp).to.equal(2);
+ expect(data.ext.newspassid.npip).to.equal(123);
+ });
+ it('should pass through GET params if present: npf, nppf, nprp, npip with alternative values', function() {
+ var specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {npf: 'false', nppf: 'true', nprp: 'xyz', npip: 'hello'};
+ };
+ const request = specMock.buildRequests(validBidRequests, validBidderRequest);
+ const data = JSON.parse(request.data);
+ expect(data.ext.newspassid.npf).to.equal(0);
+ expect(data.ext.newspassid.nppf).to.equal(1);
+ expect(data.ext.newspassid).to.not.haveOwnProperty('nprp');
+ expect(data.ext.newspassid).to.not.haveOwnProperty('npip');
+ });
+ it('should use nptestmode GET value if set, even if there is no customdata in config', function() {
+ var specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {'nptestmode': 'mytestvalue_123'};
+ };
+ const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
+ const data = JSON.parse(request.data);
+ expect(data.imp[0].ext.newspassid.customData).to.be.an('array');
+ expect(data.imp[0].ext.newspassid.customData[0].targeting.nptestmode).to.equal('mytestvalue_123');
+ });
+ it('should use GET values auction=[encoded URL] & cookiesync=[encoded url] if set', function() {
+ spec.propertyBag.config = null;
+ var specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {};
+ };
+ let request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
+ let url = request.url;
+ expect(url).to.equal('https://bidder.newspassid.com/openrtb2/auction');
+ let cookieUrl = specMock.getCookieSyncUrl();
+ expect(cookieUrl).to.equal('https://bidder.newspassid.com/static/load-cookie.html');
+ specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {'auction': 'https://www.someurl.com/auction', 'cookiesync': 'https://www.someurl.com/sync'};
+ };
+ request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
+ url = request.url;
+ expect(url).to.equal('https://www.someurl.com/auction');
+ cookieUrl = specMock.getCookieSyncUrl();
+ expect(cookieUrl).to.equal('https://www.someurl.com/sync');
+ });
+ it('should use a valid npstoredrequest GET value if set to override the placementId values, and set np_rw if we find it', function() {
+ var specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {'npstoredrequest': '1122334455'}; // 10 digits are valid
+ };
+ const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
+ const data = JSON.parse(request.data);
+ expect(data.ext.newspassid.np_rw).to.equal(1);
+ expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1122334455');
+ });
+ it('should NOT use an invalid npstoredrequest GET value if set to override the placementId values, and set np_rw to 0', function() {
+ var specMock = utils.deepClone(spec);
+ specMock.getGetParametersAsObject = function() {
+ return {'npstoredrequest': 'BADVAL'}; // 10 digits are valid
+ };
+ const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
+ const data = JSON.parse(request.data);
+ expect(data.ext.newspassid.np_rw).to.equal(0);
+ expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1310000099');
+ });
+ it('should pick up the config value of coppa & set it in the request', function () {
+ config.setConfig({'coppa': true});
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.regs).to.include.keys('coppa');
+ expect(payload.regs.coppa).to.equal(1);
+ config.resetConfig();
+ });
+ it('should pick up the config value of coppa & only set it in the request if its true', function () {
+ config.setConfig({'coppa': false});
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(utils.deepAccess(payload, 'regs.coppa')).to.be.undefined;
+ config.resetConfig();
+ });
+ it('should should contain a unique page view id in the auction request which persists across calls', function () {
+ let request = spec.buildRequests(validBidRequests, validBidderRequest);
+ let payload = JSON.parse(request.data);
+ expect(utils.deepAccess(payload, 'ext.newspassid.pv')).to.be.a('string');
+ request = spec.buildRequests(validBidRequestsIsThisCamelCaseEnough, validBidderRequest);
+ let payload2 = JSON.parse(request.data);
+ expect(utils.deepAccess(payload2, 'ext.newspassid.pv')).to.be.a('string');
+ expect(utils.deepAccess(payload2, 'ext.newspassid.pv')).to.equal(utils.deepAccess(payload, 'ext.newspassid.pv'));
+ });
+ it('should indicate that the whitelist was used when it contains valid data', function () {
+ config.setConfig({'newspassid': {'np_whitelist_adserver_keys': ['np_appnexus_pb', 'np_appnexus_imp_id']}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.ext.newspassid.np_kvp_rw).to.equal(1);
+ config.resetConfig();
+ });
+ it('should indicate that the whitelist was not used when it contains no data', function () {
+ config.setConfig({'newspassid': {'np_whitelist_adserver_keys': []}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.ext.newspassid.np_kvp_rw).to.equal(0);
+ config.resetConfig();
+ });
+ it('should indicate that the whitelist was not used when it is not set in the config', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.ext.newspassid.np_kvp_rw).to.equal(0);
+ });
+ it('should handle ortb2 site data', function () {
+ let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
+ bidderRequest.ortb2 = {
+ 'site': {
+ 'name': 'example_ortb2_name',
+ 'domain': 'page.example.com',
+ 'cat': ['IAB2'],
+ 'sectioncat': ['IAB2-2'],
+ 'pagecat': ['IAB2-2'],
+ 'page': 'https://page.example.com/here.html',
+ 'ref': 'https://ref.example.com',
+ 'keywords': 'power tools, drills',
+ 'search': 'drill'
+ }
+ };
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.imp[0].ext.newspassid.customData[0].targeting.name).to.equal('example_ortb2_name');
+ expect(payload.user.ext).to.not.have.property('gender');
+ });
+ it('should add ortb2 site data when there is no customData already created', function () {
+ let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
+ bidderRequest.ortb2 = {
+ 'site': {
+ 'name': 'example_ortb2_name',
+ 'domain': 'page.example.com',
+ 'cat': ['IAB2'],
+ 'sectioncat': ['IAB2-2'],
+ 'pagecat': ['IAB2-2'],
+ 'page': 'https://page.example.com/here.html',
+ 'ref': 'https://ref.example.com',
+ 'keywords': 'power tools, drills',
+ 'search': 'drill'
+ }
+ };
+ const request = spec.buildRequests(validBidRequestsNoCustomData, bidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.imp[0].ext.newspassid.customData[0].targeting.name).to.equal('example_ortb2_name');
+ expect(payload.imp[0].ext.newspassid.customData[0].targeting).to.not.have.property('gender')
+ });
+ it('should add ortb2 user data to the user object', function () {
+ let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
+ bidderRequest.ortb2 = {
+ 'user': {
+ 'gender': 'I identify as a box of rocks'
+ }
+ };
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
+ const payload = JSON.parse(request.data);
+ expect(payload.user.gender).to.equal('I identify as a box of rocks');
+ });
+ it('handles schain object in each bidrequest (will be the same in each br)', function () {
+ let br = JSON.parse(JSON.stringify(validBidRequests));
+ let schainConfigObject = {
+ 'ver': '1.0',
+ 'complete': 1,
+ 'nodes': [
+ {
+ 'asi': 'bidderA.com',
+ 'sid': '00001',
+ 'hp': 1
+ }
+ ]
+ };
+ br[0]['schain'] = schainConfigObject;
+ const request = spec.buildRequests(br, validBidderRequest);
+ const data = JSON.parse(request.data);
+ expect(data.source.ext).to.haveOwnProperty('schain');
+ expect(data.source.ext.schain).to.deep.equal(schainConfigObject); // .deep.equal() : Target object deeply (but not strictly) equals `{a: 1}`
+ });
+ });
+ describe('interpretResponse', function () {
+ it('should build bid array', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(result.length).to.equal(1);
+ });
+ it('should have all relevant fields', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ const bid = result[0];
+ expect(bid.cpm).to.equal(validResponse.body.seatbid[0].bid[0].cpm);
+ expect(bid.width).to.equal(validResponse.body.seatbid[0].bid[0].width);
+ expect(bid.height).to.equal(validResponse.body.seatbid[0].bid[0].height);
+ });
+ it('should build bid array with usp/CCPA', function () {
+ let validBR = JSON.parse(JSON.stringify(validBidderRequest));
+ validBR.uspConsent = '1YNY';
+ const request = spec.buildRequests(validBidRequests, validBR);
+ const payload = JSON.parse(request.data);
+ expect(payload.user.ext.uspConsent).not.to.exist;
+ expect(payload.regs.ext.us_privacy).to.equal('1YNY');
+ });
+ it('should fail ok if no seatbid in server response', function () {
+ const result = spec.interpretResponse({}, {});
+ expect(result).to.be.an('array');
+ expect(result).to.be.empty;
+ });
+ it('should fail ok if seatbid is not an array', function () {
+ const result = spec.interpretResponse({'body': {'seatbid': 'nothing_here'}}, {});
+ expect(result).to.be.an('array');
+ expect(result).to.be.empty;
+ });
+ it('should correctly parse response where there are more bidders than ad slots', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validBidResponse1adWith2Bidders, request);
+ expect(result.length).to.equal(2);
+ });
+ it('should have a ttl of 600', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(result[0].ttl).to.equal(300);
+ });
+ it('should handle a valid whitelist, removing items not on the list & leaving others', function () {
+ config.setConfig({'newspassid': {'np_whitelist_adserver_keys': ['np_appnexus_crid', 'np_appnexus_adId']}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adv')).to.be.undefined;
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adId')).to.equal('2899ec066a91ff8-0-np-0');
+ config.resetConfig();
+ });
+ it('should ignore a whitelist if enhancedAdserverTargeting is false', function () {
+ config.setConfig({'newspassid': {'np_whitelist_adserver_keys': ['np_appnexus_crid', 'np_appnexus_imp_id'], 'enhancedAdserverTargeting': false}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adv')).to.be.undefined;
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_imp_id')).to.be.undefined;
+ config.resetConfig();
+ });
+ it('should correctly handle enhancedAdserverTargeting being false', function () {
+ config.setConfig({'newspassid': {'enhancedAdserverTargeting': false}});
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_adv')).to.be.undefined;
+ expect(utils.deepAccess(result[0].adserverTargeting, 'np_appnexus_imp_id')).to.be.undefined;
+ config.resetConfig();
+ });
+ it('should add unique adId values to each bid', function() {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit));
+ const result = spec.interpretResponse(validres, request);
+ expect(result.length).to.equal(1);
+ expect(result[0]['price']).to.equal(0.9);
+ expect(result[0]['adserverTargeting']['np_npappnexus_adId']).to.equal('2899ec066a91ff8-0-np-1');
+ });
+ it('should correctly process an auction with 2 adunits & multiple bidders one of which bids for both adslots', function() {
+ let validres = JSON.parse(JSON.stringify(multiResponse1));
+ let request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest);
+ let result = spec.interpretResponse(validres, request);
+ expect(result.length).to.equal(4); // one of the 5 bids will have been removed
+ expect(result[1]['price']).to.equal(0.521);
+ expect(result[1]['impid']).to.equal('3025f169863b7f8');
+ expect(result[1]['id']).to.equal('18552976939844999');
+ expect(result[1]['adserverTargeting']['np_npappnexus_adId']).to.equal('3025f169863b7f8-0-np-2');
+ validres = JSON.parse(JSON.stringify(multiResponse1));
+ validres.body.seatbid[0].bid[1].price = 1.1;
+ validres.body.seatbid[0].bid[1].cpm = 1.1;
+ request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest);
+ result = spec.interpretResponse(validres, request);
+ expect(result[1]['price']).to.equal(1.1);
+ expect(result[1]['impid']).to.equal('3025f169863b7f8');
+ expect(result[1]['id']).to.equal('18552976939844681');
+ expect(result[1]['adserverTargeting']['np_npappnexus_adId']).to.equal('3025f169863b7f8-0-np-1');
+ });
+ });
+ describe('userSyncs', function () {
+ it('should fail gracefully if no server response', function () {
+ const result = spec.getUserSyncs('bad', false, emptyObject);
+ expect(result).to.be.empty;
+ });
+ it('should fail gracefully if server response is empty', function () {
+ const result = spec.getUserSyncs('bad', [], emptyObject);
+ expect(result).to.be.empty;
+ });
+ it('should append the various values if they exist', function() {
+ spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', emptyObject);
+ expect(result).to.be.an('array');
+ expect(result[0].url).to.include('publisherId=9876abcd12-3');
+ expect(result[0].url).to.include('siteId=1234567890');
+ });
+ it('should append ccpa (usp data)', function() {
+ spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', emptyObject, '1YYN');
+ expect(result).to.be.an('array');
+ expect(result[0].url).to.include('usp_consent=1YYN');
+ });
+ it('should use "" if no usp is sent to cookieSync', function() {
+ spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', emptyObject);
+ expect(result).to.be.an('array');
+ expect(result[0].url).to.include('usp_consent=&');
+ });
+ });
+ describe('default size', function () {
+ it('should should return default sizes if no obj is sent', function () {
+ let obj = '';
+ const result = defaultSize(obj);
+ expect(result.defaultHeight).to.equal(250);
+ expect(result.defaultWidth).to.equal(300);
+ });
+ });
+ describe('getGranularityKeyName', function() {
+ it('should return a string granularity as-is', function() {
+ const result = getGranularityKeyName('', 'this is it', '');
+ expect(result).to.equal('this is it');
+ });
+ it('should return "custom" for a mediaTypeGranularity object', function() {
+ const result = getGranularityKeyName('', {}, '');
+ expect(result).to.equal('custom');
+ });
+ it('should return "custom" for a mediaTypeGranularity object', function() {
+ const result = getGranularityKeyName('', false, 'string buckets');
+ expect(result).to.equal('string buckets');
+ });
+ });
+ describe('getGranularityObject', function() {
+ it('should return an object as-is', function() {
+ const result = getGranularityObject('', {'name': 'mark'}, '', '');
+ expect(result.name).to.equal('mark');
+ });
+ it('should return an object as-is', function() {
+ const result = getGranularityObject('', false, 'custom', {'name': 'rupert'});
+ expect(result.name).to.equal('rupert');
+ });
+ });
+ describe('blockTheRequest', function() {
+ it('should return true if np_request is false', function() {
+ config.setConfig({'newspassid': {'np_request': false}});
+ let result = spec.blockTheRequest();
+ expect(result).to.be.true;
+ config.resetConfig();
+ });
+ it('should return false if np_request is true', function() {
+ config.setConfig({'newspassid': {'np_request': true}});
+ let result = spec.blockTheRequest();
+ expect(result).to.be.false;
+ config.resetConfig();
+ });
+ });
+ describe('getPageId', function() {
+ it('should return the same Page ID for multiple calls', function () {
+ let result = spec.getPageId();
+ expect(result).to.be.a('string');
+ let result2 = spec.getPageId();
+ expect(result2).to.equal(result);
+ });
+ });
+ describe('getBidRequestForBidId', function() {
+ it('should locate a bid inside a bid array', function () {
+ let result = spec.getBidRequestForBidId('2899ec066a91ff8', validBidRequestsMulti);
+ expect(result.testId).to.equal(1);
+ result = spec.getBidRequestForBidId('2899ec066a91ff0', validBidRequestsMulti);
+ expect(result.testId).to.equal(2);
+ });
+ });
+ describe('removeSingleBidderMultipleBids', function() {
+ it('should remove the multi bid by npappnexus for adslot 2d30e86db743a8', function() {
+ let validres = JSON.parse(JSON.stringify(multiResponse1));
+ expect(validres.body.seatbid[0].bid.length).to.equal(3);
+ expect(validres.body.seatbid[0].seat).to.equal('npappnexus');
+ let response = spec.removeSingleBidderMultipleBids(validres.body.seatbid);
+ expect(response.length).to.equal(2);
+ expect(response[0].bid.length).to.equal(2);
+ expect(response[0].seat).to.equal('npappnexus');
+ expect(response[1].bid.length).to.equal(2);
+ });
+ });
+});
diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js
index a8aa62f24d1..303025888dc 100644
--- a/test/spec/modules/nextMillenniumBidAdapter_spec.js
+++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js
@@ -14,6 +14,16 @@ describe('nextMillenniumBidAdapterTests', function() {
gdprConsent: {
consentString: 'kjfdniwjnifwenrif3',
gdprApplies: true
+ },
+ ortb2: {
+ device: {
+ w: 1500,
+ h: 1000
+ },
+ site: {
+ domain: 'example.com',
+ page: 'http://example.com'
+ }
}
}
];
@@ -94,6 +104,28 @@ describe('nextMillenniumBidAdapterTests', function() {
expect(JSON.parse(request[0].data).ext.nextMillennium.refresh_count).to.equal(3);
});
+ it('Check if domain was added', function() {
+ const request = spec.buildRequests(bidRequestData)
+ expect(JSON.parse(request[0].data).site.domain).to.exist
+ })
+
+ it('Check if elOffsets was added', function() {
+ const request = spec.buildRequests(bidRequestData)
+ expect(JSON.parse(request[0].data).ext.nextMillennium.elOffsets).to.be.an('object')
+ })
+
+ it('Check if imp object was added', function() {
+ const request = spec.buildRequests(bidRequestData)
+ expect(JSON.parse(request[0].data).imp).to.be.an('array')
+ })
+
+ it('Check if imp prebid stored id is correct', function() {
+ const request = spec.buildRequests(bidRequestData)
+ const requestData = JSON.parse(request[0].data);
+ const storedReqId = requestData.ext.prebid.storedrequest.id;
+ expect(requestData.imp[0].ext.prebid.storedrequest.id).to.equal(storedReqId)
+ })
+
it('Test getUserSyncs function', function () {
const syncOptions = {
'iframeEnabled': true
diff --git a/test/spec/modules/nextrollIdSystem_spec.js b/test/spec/modules/nextrollIdSystem_spec.js
deleted file mode 100644
index d89c7fe3c98..00000000000
--- a/test/spec/modules/nextrollIdSystem_spec.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import { nextrollIdSubmodule, storage } from 'modules/nextrollIdSystem.js';
-
-const LS_VALUE = `{
- "AdID":{"id":"adid","key":"AdID"},
- "AdID:1002": {"id":"adid","key":"AdID:1002","value":"id_value"}}`;
-
-describe('NextrollId module', function () {
- let sandbox = sinon.sandbox.create();
- let hasLocalStorageStub;
- let getLocalStorageStub;
-
- beforeEach(function() {
- hasLocalStorageStub = sandbox.stub(storage, 'hasLocalStorage');
- getLocalStorageStub = sandbox.stub(storage, 'getDataFromLocalStorage');
- });
-
- afterEach(function () {
- sandbox.restore();
- })
-
- const testCases = [
- {
- expect: {
- id: {nextrollId: 'id_value'},
- },
- params: {partnerId: '1002'},
- localStorage: LS_VALUE
- },
- {
- expect: {id: undefined},
- params: {partnerId: '1003'},
- localStorage: LS_VALUE
- },
- {
- expect: {id: undefined},
- params: {partnerId: ''},
- localStorage: LS_VALUE
- },
- {
- expect: {id: undefined},
- params: {partnerId: '102'},
- localStorage: undefined
- },
- {
- expect: {id: undefined},
- params: undefined,
- localStorage: undefined
- }
- ]
- testCases.forEach(
- (testCase, i) => it(`getId() (TC #${i}) should return the nextroll id if it exists`, function () {
- getLocalStorageStub.withArgs('dca0.com').returns(testCase.localStorage);
- const id = nextrollIdSubmodule.getId({params: testCase.params});
- expect(id).to.be.deep.equal(testCase.expect);
- }))
-});
diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js
index eccf0e84031..7ea89f7dd3f 100644
--- a/test/spec/modules/nobidBidAdapter_spec.js
+++ b/test/spec/modules/nobidBidAdapter_spec.js
@@ -70,7 +70,7 @@ describe('Nobid Adapter', function () {
];
let bidderRequest = {
- refererInfo: {referer: REFERER}, bidderCode: BIDDER_CODE
+ refererInfo: {page: REFERER}, bidderCode: BIDDER_CODE
}
const siteName = 'example';
@@ -84,22 +84,20 @@ describe('Nobid Adapter', function () {
const sitePageCat = 'IAB2-12';
it('ortb2 should exist', function () {
- config.setConfig({
- ortb2: {
- site: {
- name: siteName,
- domain: siteDomain,
- cat: [ siteCat ],
- sectioncat: [ siteSectionCat ],
- pagecat: [ sitePageCat ],
- page: sitePage,
- ref: siteRef,
- keywords: siteKeywords,
- search: siteSearch
- }
+ const ortb2 = {
+ site: {
+ name: siteName,
+ domain: siteDomain,
+ cat: [ siteCat ],
+ sectioncat: [ siteSectionCat ],
+ pagecat: [ sitePageCat ],
+ page: sitePage,
+ ref: siteRef,
+ keywords: siteKeywords,
+ search: siteSearch
}
- });
- const request = spec.buildRequests(bidRequests, bidderRequest);
+ };
+ const request = spec.buildRequests(bidRequests, {...bidderRequest, ortb2});
let payload = JSON.parse(request.data);
payload = JSON.parse(JSON.stringify(payload));
expect(payload.sid).to.equal(SITE_ID);
@@ -134,7 +132,7 @@ describe('Nobid Adapter', function () {
];
let bidderRequest = {
- refererInfo: {referer: REFERER}, bidderCode: BIDDER_CODE
+ refererInfo: {page: REFERER}, bidderCode: BIDDER_CODE
}
it('should add source and version to the tag', function () {
@@ -308,7 +306,7 @@ describe('Nobid Adapter', function () {
];
let bidderRequest = {
- refererInfo: {referer: REFERER}
+ refererInfo: {page: REFERER}
}
it('should add source and version to the tag', function () {
@@ -397,7 +395,7 @@ describe('Nobid Adapter', function () {
];
let bidderRequest = {
- refererInfo: {referer: REFERER}
+ refererInfo: {page: REFERER}
}
it('should add source and version to the tag', function () {
@@ -483,7 +481,7 @@ describe('Nobid Adapter', function () {
];
let bidderRequest = {
- refererInfo: {referer: REFERER}
+ refererInfo: {page: REFERER}
}
it('should criteo eid', function () {
@@ -517,7 +515,7 @@ describe('Nobid Adapter', function () {
];
let bidderRequest = {
- refererInfo: {referer: REFERER}
+ refererInfo: {page: REFERER}
}
it('should add source and version to the tag', function () {
@@ -651,7 +649,7 @@ describe('Nobid Adapter', function () {
];
let bidderRequest = {
- refererInfo: {referer: REFERER}
+ refererInfo: {page: REFERER}
}
it('should refreshCount = 4', function () {
diff --git a/test/spec/modules/oguryBidAdapter_spec.js b/test/spec/modules/oguryBidAdapter_spec.js
index 028c780d9fb..8871d2d0886 100644
--- a/test/spec/modules/oguryBidAdapter_spec.js
+++ b/test/spec/modules/oguryBidAdapter_spec.js
@@ -279,7 +279,7 @@ describe('OguryBidAdapter', function () {
},
ext: {
prebidversion: '$prebid.version$',
- adapterversion: '1.2.12'
+ adapterversion: '1.2.13'
},
device: {
w: stubbedWidth,
@@ -659,7 +659,7 @@ describe('OguryBidAdapter', function () {
advertiserDomains: openRtbBidResponse.body.seatbid[0].bid[0].adomain
},
nurl: openRtbBidResponse.body.seatbid[0].bid[0].nurl,
- adapterVersion: '1.2.12',
+ adapterVersion: '1.2.13',
prebidVersion: '$prebid.version$'
}, {
requestId: openRtbBidResponse.body.seatbid[0].bid[1].impid,
@@ -676,7 +676,7 @@ describe('OguryBidAdapter', function () {
advertiserDomains: openRtbBidResponse.body.seatbid[0].bid[1].adomain
},
nurl: openRtbBidResponse.body.seatbid[0].bid[1].nurl,
- adapterVersion: '1.2.12',
+ adapterVersion: '1.2.13',
prebidVersion: '$prebid.version$'
}]
diff --git a/test/spec/modules/oneKeyIdSystem_spec.js b/test/spec/modules/oneKeyIdSystem_spec.js
new file mode 100644
index 00000000000..9172a61df79
--- /dev/null
+++ b/test/spec/modules/oneKeyIdSystem_spec.js
@@ -0,0 +1,107 @@
+import { oneKeyIdSubmodule } from 'modules/oneKeyIdSystem'
+
+const defaultConf = {
+ params: {
+ proxyHostName: 'proxy.com'
+ }
+};
+
+const defaultIdsAndPreferences = {
+ identifiers: [
+ {
+ version: '0.1',
+ type: 'paf_browser_id',
+ value: 'df0a5664-987d-4074-bbd9-e9b12ebae6ef',
+ source: {
+ domain: 'crto-poc-1.onekey.network',
+ timestamp: 1657100291,
+ signature: 'ikjV6WwpcroNB5XyLOr3MgYHLpS6UjICEOuv/jEr00uVrjZm0zluDSWh11OeGDZrMhxMBPeTabtQ4U2rNk3IzQ=='
+ }
+ }
+ ],
+ preferences: {
+ version: '0.1',
+ data: {
+ use_browsing_for_personalization: true
+ },
+ source: {
+ domain: 'cmp.pafdemopublisher.com',
+ timestamp: 1657100294,
+ signature: 'aAbMThxyeKpe/EgT5ARI1xecjCwwh0uRagsTuPXNY2fzh7foeW31qljDZf6h8UwOd9M2bAN7XNtM2LYBbJzskQ=='
+ }
+ }
+};
+
+const defaultIdsAndPreferencesResult = {
+ status: 'PARTICIPATING',
+ data: defaultIdsAndPreferences
+};
+
+describe('oneKeyData module', () => {
+ describe('getId function', () => {
+ beforeEach(() => {
+ setUpOneKey();
+ });
+
+ it('return a callback for handling asynchron results', () => {
+ const moduleIdResponse = oneKeyIdSubmodule.getId(defaultConf);
+
+ expect(moduleIdResponse.callback).to.be.an('function');
+ });
+
+ it(`return a callback that waits for OneKey to be loaded`, () => {
+ const moduleIdResponse = oneKeyIdSubmodule.getId(defaultConf);
+
+ moduleIdResponse.callback(function() {})
+
+ expect(window.OneKey.queue.length).to.equal(1);
+ });
+
+ it('return a callback that gets ids and prefs', () => {
+ const moduleIdResponse = oneKeyIdSubmodule.getId(defaultConf);
+
+ // Act
+ return new Promise((resolve) => {
+ moduleIdResponse.callback(resolve);
+ executeOneKeyQueue();
+ })
+
+ // Assert
+ .then((idsAndPrefs) => {
+ expect(idsAndPrefs).to.equal(defaultIdsAndPreferences);
+ });
+ });
+
+ it('return a callback with undefined if impossible to get ids and prefs', () => {
+ window.OneKey.getIdsAndPreferences = () => {
+ return Promise.reject(new Error(`Impossible to get ids and prefs`));
+ };
+ const moduleIdResponse = oneKeyIdSubmodule.getId(defaultConf);
+
+ // Act
+ return new Promise((resolve) => {
+ moduleIdResponse.callback(resolve);
+ executeOneKeyQueue();
+ })
+
+ // Assert
+ .then((idsAndPrefs) => {
+ expect(idsAndPrefs).to.be.undefined;
+ });
+ });
+ });
+});
+
+const setUpOneKey = () => {
+ window.OneKey.queue = [];
+ window.OneKey.getIdsAndPreferences = () => {
+ return Promise.resolve(defaultIdsAndPreferencesResult);
+ };
+}
+
+const executeOneKeyQueue = () => {
+ while (window.OneKey.queue.length > 0) {
+ window.OneKey.queue[0]();
+ window.OneKey.queue.shift();
+ }
+}
diff --git a/test/spec/modules/oneKeyRtdProvider_spec.js b/test/spec/modules/oneKeyRtdProvider_spec.js
new file mode 100644
index 00000000000..70023e35196
--- /dev/null
+++ b/test/spec/modules/oneKeyRtdProvider_spec.js
@@ -0,0 +1,152 @@
+import {oneKeyDataSubmodule} from 'modules/oneKeyRtdProvider.js';
+import {getAdUnits} from '../../fixtures/fixtures.js';
+
+const defaultSeed = {
+ version: '0.1',
+ transaction_ids: [
+ 'd566b02a-a6e2-4c87-98dc-f5623cd9e828',
+ 'f7ffe3cc-0d58-4ec4-b687-1d3d410a48fe'
+ ],
+ publisher: 'cmp.pafdemopublisher.com',
+ source: {
+ domain: 'cmp.pafdemopublisher.com',
+ timestamp: 1657116880,
+ signature: '6OmdrSGwagPpugGFuQ4VGjzqYadHxWIXPaLItk0vA1lmi/EQyRvNF5seXStfwKWRnC7HZlOIGSjA6g7HAuofWw=='
+
+ }
+};
+
+const defaultOrb2WithTransmission = {
+ user: {
+ ext: {
+ paf: {
+ transmission: {
+ seed: defaultSeed
+ }
+ }
+ }
+ }
+};
+
+const defaultRtdConfig = {
+ params: {
+ proxyHostName: 'host'
+ }
+};
+
+describe('oneKeyDataSubmodule', () => {
+ var bidsConfig;
+ beforeEach(() => {
+ // Fresh bidsConfig because it can be altered
+ // during the tests.
+ bidsConfig = getReqBidsConfig();
+ setUpOneKey();
+ });
+
+ it('successfully instantiates', () => {
+ expect(oneKeyDataSubmodule.init()).to.equal(true);
+ });
+
+ it('call OneKey API once it is loaded', () => {
+ const done = sinon.spy();
+
+ oneKeyDataSubmodule.getBidRequestData(bidsConfig, done, defaultRtdConfig);
+
+ expect(bidsConfig).to.eql(getReqBidsConfig());
+ expect(done.callCount).to.equal(0);
+ expect(window.OneKey.queue.length).to.equal(1);
+ });
+
+ it('don\'t change anything without a seed', () => {
+ window.OneKey.generateSeed = (_transactionIds) => {
+ return Promise.resolve(undefined);
+ };
+
+ // Act
+ return new Promise(resolve => {
+ oneKeyDataSubmodule.getBidRequestData(bidsConfig, resolve, defaultRtdConfig);
+ executeOneKeyQueue();
+ })
+
+ // Assert
+ .then(() => {
+ expect(bidsConfig).to.eql(getReqBidsConfig());
+ });
+ });
+
+ [ // Test cases
+ {
+ description: 'global orb2',
+ rtdConfig: defaultRtdConfig,
+ expectedFragment: {
+ global: {
+ ...defaultOrb2WithTransmission
+ },
+ bidder: {}
+ }
+ },
+
+ {
+ description: 'bidder-specific orb2',
+ rtdConfig: {
+ params: {
+ proxyHostName: 'host',
+ bidders: [ 'bidder42', 'bidder24' ]
+ }
+ },
+ expectedFragment: {
+ global: { },
+ bidder: {
+ bidder42: {
+ ...defaultOrb2WithTransmission
+ },
+ bidder24: {
+ ...defaultOrb2WithTransmission
+ }
+ }
+ }
+ }
+ ].forEach(testCase => {
+ it(`update adUnits with transaction-ids and transmission in ${testCase.description}`, () => {
+ // Act
+ return new Promise(resolve => {
+ oneKeyDataSubmodule.getBidRequestData(bidsConfig, resolve, testCase.rtdConfig);
+ executeOneKeyQueue();
+ })
+
+ // Assert
+ .then(() => {
+ // Verify transaction-ids without equality
+ // because they are generated UUID.
+ bidsConfig.adUnits.forEach((adUnit) => {
+ expect(adUnit.ortb2Imp.ext.data.paf.transaction_id).to.not.be.undefined;
+ });
+ expect(bidsConfig.ortb2Fragments).to.eql(testCase.expectedFragment);
+ });
+ });
+ });
+});
+
+const getReqBidsConfig = () => {
+ return {
+ adUnits: getAdUnits(),
+ ortb2Fragments: {
+ global: {},
+ bidder: {}
+ }
+ }
+}
+
+const setUpOneKey = () => {
+ window.OneKey.queue = [];
+ OneKey.generateSeed = (_transactionIds) => {
+ return Promise.resolve(defaultSeed);
+ };
+}
+
+const executeOneKeyQueue = () => {
+ while (window.OneKey.queue.length > 0) {
+ window.OneKey.queue[0]();
+ window.OneKey.queue.shift();
+ }
+}
diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js
deleted file mode 100644
index d6dacb44529..00000000000
--- a/test/spec/modules/oneVideoBidAdapter_spec.js
+++ /dev/null
@@ -1,1046 +0,0 @@
-import { expect } from 'chai';
-import { spec } from 'modules/oneVideoBidAdapter.js';
-
-describe('OneVideoBidAdapter', function () {
- let bidRequest;
- let bidderRequest = {
- 'bidderCode': 'oneVideo',
- 'auctionId': 'e158486f-8c7f-472f-94ce-b0cbfbb50ab4',
- 'bidderRequestId': '1e498b84fffc39',
- 'bids': bidRequest,
- 'auctionStart': 1520001292880,
- 'timeout': 3000,
- 'start': 1520001292884,
- 'doneCbCallCount': 0,
- 'refererInfo': {
- 'numIframes': 1,
- 'reachedTop': true,
- 'referer': 'test.com'
- }
- };
- let mockConfig;
-
- beforeEach(function () {
- bidRequest = {
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [640, 480]
- }
- },
- bidder: 'oneVideo',
- sizes: [640, 480],
- bidId: '30b3efwfwe1e',
- adUnitCode: 'video1',
- params: {
- video: {
- playerWidth: 640,
- playerHeight: 480,
- mimes: ['video/mp4', 'application/javascript'],
- protocols: [2, 5],
- api: [2],
- position: 1,
- delivery: [2],
- playbackmethod: [1, 5],
- sid: 134,
- rewarded: 1,
- placement: 1,
- hp: 1,
- inventoryid: 123
- },
- site: {
- id: 1,
- page: 'https://news.yahoo.com/portfolios',
- referrer: 'http://www.yahoo.com'
- },
- pubId: 'brxd'
- }
- };
- });
-
- describe('spec.isBidRequestValid', function () {
- it('should return false when mediaTypes video OR banner not declared', function () {
- bidRequest.mediaTypes = {};
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- });
-
- it('should return true (skip validations) when e2etest = true', function () {
- bidRequest.params.video = {
- e2etest: true
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
- it('should return true when mediaTypes.video has all mandatory params', function () {
- bidRequest.mediaTypes.video = {
- context: 'instream',
- playerSize: [640, 480],
- mimes: ['video/mp4', 'application/javascript'],
- }
- bidRequest.params.video = {};
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
- it('should return true when params.video has all override params instead of mediaTypes.video', function () {
- bidRequest.mediaTypes.video = {
- context: 'instream'
- };
- bidRequest.params.video = {
- playerWidth: 640,
- playerHeight: 480,
- mimes: ['video/mp4', 'application/javascript']
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
- it('should return true when playerWidth & playerHeight are passed in params.video', function () {
- bidRequest.mediaTypes.video = {
- context: 'instream',
- mimes: ['video/mp4', 'application/javascript']
- };
- bidRequest.params.video = {
- playerWidth: 640,
- playerHeight: 480,
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
- it('should return true when mimes is passed in params.video', function () {
- bidRequest.mediaTypes.video = {
- context: 'instream',
- playerSizes: [640, 480]
- };
- bidRequest.video = {
- mimes: ['video/mp4', 'application/javascript']
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
- it('should return false when both mediaTypes.video and params.video Objects are missing', function () {
- bidRequest.mediaTypes = {};
- bidRequest.params = {
- pubId: 'brxd'
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- });
-
- it('should return false when both mediaTypes.video and params.video are missing mimes and player size', function () {
- bidRequest.mediaTypes = {
- video: {
- context: 'instream'
- }
- };
- bidRequest.params = {
- pubId: 'brxd'
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- });
-
- it('should return false when the "pubId" param is missing', function () {
- bidRequest.params = {
- video: {
- playerWidth: 480,
- playerHeight: 640,
- mimes: ['video/mp4', 'application/javascript'],
- }
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- });
-
- it('should return true when the "pubId" param exists', function () {
- bidRequest.mediaTypes = {
- video: {
- playerSizes: [640, 480],
- mimes: ['video/mp4', 'application/javascript']
- },
- pubId: 'brxd'
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- });
-
- it('should return false when no bid params are passed', function () {
- bidRequest.params = {};
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- });
-
- it('should return false when the mediaType is "banner" and display="undefined" (DAP 3P)', function () {
- bidRequest = {
- mediaTypes: {
- banner: {
- sizes: [640, 480]
- }
- }
- }
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- })
-
- it('should return true when the mediaType is "banner" and display=1 (DAP 3P)', function () {
- bidRequest = {
- mediaTypes: {
- banner: {
- sizes: [640, 480]
- }
- },
- bidder: 'oneVideo',
- sizes: [640, 480],
- bidId: '30b3efwfwe1e',
- adUnitCode: 'video1',
- params: {
- video: {
- playerWidth: 640,
- playerHeight: 480,
- mimes: ['video/mp4', 'application/javascript'],
- protocols: [2, 5],
- api: [2],
- position: 1,
- delivery: [2],
- playbackmethod: [1, 5],
- sid: 134,
- rewarded: 1,
- placement: 1,
- inventoryid: 123,
- display: 1
- },
- site: {
- id: 1,
- page: 'https://news.yahoo.com/portfolios',
- referrer: 'http://www.yahoo.com'
- },
- pubId: 'brxd'
- }
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- })
-
- it('should return false when the mediaType is "video" and context="outstream" and display=1 (DAP 3P)', function () {
- bidRequest = {
- mediaTypes: {
- video: {
- context: 'outstream',
- playerSize: [640, 480]
- }
- },
- params: {
- video: {
- display: 1
- }
- }
- }
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- })
-
- it('should return true for Multi-Format AdUnits, when the mediaTypes are both "banner" and "video" (Multi-Format Support)', function () {
- bidRequest = {
- mediaTypes: {
- banner: {
- sizes: [640, 480]
- },
- video: {
- context: 'outstream',
- playerSize: [640, 480],
- mimes: ['video/mp4', 'application/javascript']
- }
- },
- bidder: 'oneVideo',
- sizes: [640, 480],
- bidId: '30b3efwfwe1e',
- adUnitCode: 'video1',
- params: {
- video: {
- protocols: [2, 5],
- api: [2]
- },
- site: {
- page: 'https://news.yahoo.com/portfolios',
- referrer: 'http://www.yahoo.com'
- },
- pubId: 'brxd'
- }
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- })
- });
-
- describe('spec.buildRequests', function () {
- it('should create a POST request for every bid', function () {
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- expect(requests[0].method).to.equal('POST');
- expect(requests[0].url).to.equal(spec.ENDPOINT + bidRequest.params.pubId);
- });
-
- it('should attach the bid request object', function () {
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- expect(requests[0].bidRequest).to.equal(bidRequest);
- });
-
- it('should attach request data', function () {
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const [width, height] = bidRequest.sizes;
- const placement = bidRequest.params.video.placement;
- const rewarded = bidRequest.params.video.rewarded;
- const inventoryid = bidRequest.params.video.inventoryid;
- const VERSION = '3.1.2';
- expect(data.imp[0].video.w).to.equal(width);
- expect(data.imp[0].video.h).to.equal(height);
- expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor);
- expect(data.imp[0].ext.rewarded).to.equal(rewarded);
- expect(data.imp[0].video.placement).to.equal(placement);
- expect(data.imp[0].ext.inventoryid).to.equal(inventoryid);
- expect(data.imp[0].ext.prebidver).to.equal('$prebid.version$');
- expect(data.imp[0].ext.adapterver).to.equal(VERSION);
- });
-
- it('must parse bid size from a nested array', function () {
- const width = 640;
- const height = 480;
- bidRequest.sizes = [
- [width, height]
- ];
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].video.w).to.equal(width);
- expect(data.imp[0].video.h).to.equal(height);
- });
-
- it('should set pubId to HBExchange when bid.params.video.e2etest = true', function () {
- bidRequest.params.video.e2etest = true;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- expect(requests[0].method).to.equal('POST');
- expect(requests[0].url).to.equal(spec.E2ETESTENDPOINT + 'HBExchange');
- });
-
- it('should attach End 2 End test data', function () {
- bidRequest.params.video.e2etest = true;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].bidfloor).to.not.exist;
- expect(data.imp[0].video.w).to.equal(300);
- expect(data.imp[0].video.h).to.equal(250);
- expect(data.imp[0].video.mimes).to.eql(['video/mp4', 'application/javascript']);
- expect(data.imp[0].video.api).to.eql([2]);
- expect(data.site.page).to.equal('https://verizonmedia.com');
- expect(data.site.ref).to.equal('https://verizonmedia.com');
- expect(data.tmax).to.equal(1000);
- });
-
- it('it should create new schain and send it if video.params.sid exists', function () {
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const schain = data.source.ext.schain;
- expect(schain.nodes.length).to.equal(1);
- expect(schain.nodes[0].sid).to.equal(bidRequest.params.video.sid);
- expect(schain.nodes[0].rid).to.equal(data.id);
- })
-
- it('should send Global or Bidder specific schain if sid is not passed in video.params.sid', function () {
- bidRequest.params.video.sid = null;
- const globalSchain = {
- ver: '1.0',
- complete: 1,
- nodes: [{
- asi: 'some-platform.com',
- sid: '111111',
- rid: bidRequest.id,
- hp: 1
- }]
- };
- bidRequest.schain = globalSchain;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const schain = data.source.ext.schain;
- expect(schain.nodes.length).to.equal(1);
- expect(schain).to.equal(globalSchain);
- });
-
- it('should ignore Global or Bidder specific schain if video.params.sid exists and send new schain', function () {
- const globalSchain = {
- ver: '1.0',
- complete: 1,
- nodes: [{
- asi: 'some-platform.com',
- sid: '111111',
- rid: bidRequest.id,
- hp: 1
- }]
- };
- bidRequest.schain = globalSchain;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const schain = data.source.ext.schain;
- expect(schain.nodes.length).to.equal(1);
- expect(schain.complete).to.equal(1);
- expect(schain.nodes[0].sid).to.equal(bidRequest.params.video.sid);
- expect(schain.nodes[0].rid).to.equal(data.id);
- })
-
- it('should append hp to new schain created by sid if video.params.hp is passed', function () {
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const schain = data.source.ext.schain;
- expect(schain.nodes[0].hp).to.equal(bidRequest.params.video.hp);
- })
- it('should not accept key values pairs if custom is Undefined ', function () {
- bidRequest.params.video.custom = null;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].ext.custom).to.be.undefined;
- });
- it('should not accept key values pairs if custom is Array ', function () {
- bidRequest.params.video.custom = [];
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].ext.custom).to.be.undefined;
- });
- it('should not accept key values pairs if custom is Number ', function () {
- bidRequest.params.video.custom = 123456;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].ext.custom).to.be.undefined;
- });
- it('should not accept key values pairs if custom is String ', function () {
- bidRequest.params.video.custom = 'keyValuePairs';
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].ext.custom).to.be.undefined;
- });
- it('should not accept key values pairs if custom is Boolean ', function () {
- bidRequest.params.video.custom = true;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].ext.custom).to.be.undefined;
- });
- it('should accept key values pairs if custom is Object ', function () {
- bidRequest.params.video.custom = {};
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.imp[0].ext.custom).to.be.a('object');
- });
- it('should accept key values pairs if custom is Object ', function () {
- bidRequest.params.video.custom = {
- key1: 'value1',
- key2: 'value2',
- key3: 4444444,
- key4: false,
- key5: {
- nested: 'object'
- },
- key6: ['string', 2, true, null],
- key7: null,
- key8: undefined
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const custom = requests[0].data.imp[0].ext.custom;
- expect(custom['key1']).to.be.a('string');
- expect(custom['key2']).to.be.a('string');
- expect(custom['key3']).to.be.a('number');
- expect(custom['key4']).to.not.exist;
- expect(custom['key5']).to.not.exist;
- expect(custom['key6']).to.not.exist;
- expect(custom['key7']).to.not.exist;
- expect(custom['key8']).to.not.exist;
- });
-
- describe('content object validations', function () {
- it('should not accept content object if value is Undefined ', function () {
- bidRequest.params.video.content = null;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.undefined;
- });
- it('should not accept content object if value is is Array ', function () {
- bidRequest.params.video.content = [];
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.undefined;
- });
- it('should not accept content object if value is Number ', function () {
- bidRequest.params.video.content = 123456;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.undefined;
- });
- it('should not accept content object if value is String ', function () {
- bidRequest.params.video.content = 'keyValuePairs';
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.undefined;
- });
- it('should not accept content object if value is Boolean ', function () {
- bidRequest.params.video.content = true;
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.undefined;
- });
- it('should accept content object if value is Object ', function () {
- bidRequest.params.video.content = {};
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.a('object');
- });
-
- it('should not append unsupported content object keys', function () {
- bidRequest.params.video.content = {
- fake: 'news',
- unreal: 'param',
- counterfit: 'data'
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.empty;
- });
-
- it('should not append content string parameters if value is not string ', function () {
- bidRequest.params.video.content = {
- id: 1234,
- title: ['Title'],
- series: ['Series'],
- season: ['Season'],
- genre: ['Genre'],
- contentrating: {1: 'C-Rating'},
- language: {1: 'EN'}
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.a('object');
- expect(data.site.content).to.be.empty
- });
- it('should not append content Number parameters if value is not Number ', function () {
- bidRequest.params.video.content = {
- episode: '1',
- context: 'context',
- livestream: {0: 'stream'},
- len: [360],
- prodq: [1],
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.a('object');
- expect(data.site.content).to.be.empty
- });
- it('should not append content Array parameters if value is not Array ', function () {
- bidRequest.params.video.content = {
- cat: 'categories',
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.a('object');
- expect(data.site.content).to.be.empty
- });
- it('should not append content ext if value is not Object ', function () {
- bidRequest.params.video.content = {
- ext: 'content.ext',
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.be.a('object');
- expect(data.site.content).to.be.empty
- });
- it('should append supported parameters if value match validations ', function () {
- bidRequest.params.video.content = {
- id: '1234',
- title: 'Title',
- series: 'Series',
- season: 'Season',
- cat: [
- 'IAB1'
- ],
- genre: 'Genre',
- contentrating: 'C-Rating',
- language: 'EN',
- episode: 1,
- prodq: 1,
- context: 1,
- livestream: 0,
- len: 360,
- ext: {}
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.site.content).to.deep.equal(bidRequest.params.video.content);
- });
- });
- });
-
- describe('price floor module validations', function () {
- beforeEach(function () {
- bidRequest.getFloor = (floorObj) => {
- return {
- floor: bidRequest.floors.values[floorObj.mediaType + '|640x480'],
- currency: floorObj.currency,
- mediaType: floorObj.mediaType
- }
- }
- });
-
- it('should get bidfloor from getFloor method', function () {
- bidRequest.params.cur = 'EUR';
- bidRequest.floors = {
- currency: 'EUR',
- values: {
- 'video|640x480': 5.55
- }
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.cur).is.a('string');
- expect(data.cur).to.equal('EUR');
- expect(data.imp[0].bidfloor).is.a('number');
- expect(data.imp[0].bidfloor).to.equal(5.55);
- });
-
- it('should use adUnit/module currency & floor instead of bid.params.bidfloor', function () {
- bidRequest.params.cur = 'EUR';
- bidRequest.params.bidfloor = 3.33;
- bidRequest.floors = {
- currency: 'EUR',
- values: {
- 'video|640x480': 5.55
- }
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.cur).is.a('string');
- expect(data.cur).to.equal('EUR');
- expect(data.imp[0].bidfloor).is.a('number');
- expect(data.imp[0].bidfloor).to.equal(5.55);
- });
-
- it('should load banner instead of video floor when DAP is active bid.params.video.display = 1', function () {
- bidRequest.params.video.display = 1;
- bidRequest.params.cur = 'EUR';
- bidRequest.mediaTypes = {
- banner: {
- sizes: [
- [640, 480]
- ]
- }
- };
- bidRequest.floors = {
- currency: 'EUR',
- values: {
- 'banner|640x480': 2.22,
- 'video|640x480': 9.99
- }
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.cur).is.a('string');
- expect(data.cur).to.equal('EUR');
- expect(data.imp[0].bidfloor).is.a('number');
- expect(data.imp[0].bidfloor).to.equal(2.22);
- })
-
- it('should load video floor when multi-format adUnit is present', function () {
- bidRequest.params.cur = 'EUR';
- bidRequest.mediaTypes.banner = {
- sizes: [
- [640, 480]
- ]
- };
- bidRequest.floors = {
- currency: 'EUR',
- values: {
- 'banner|640x480': 2.22,
- 'video|640x480': 9.99
- }
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- expect(data.cur).is.a('string');
- expect(data.cur).to.equal('EUR');
- expect(data.imp[0].bidfloor).is.a('number');
- expect(data.imp[0].bidfloor).to.equal(9.99);
- })
- })
-
- describe('spec.interpretResponse', function () {
- it('should return no bids if the response is not valid', function () {
- const bidResponse = spec.interpretResponse({
- body: null
- }, {
- bidRequest
- });
- expect(bidResponse.length).to.equal(0);
- });
-
- it('should return no bids if the response "nurl" and "adm" are missing', function () {
- const serverResponse = {
- seatbid: [{
- bid: [{
- price: 6.01
- }]
- }]
- };
- const bidResponse = spec.interpretResponse({
- body: serverResponse
- }, {
- bidRequest
- });
- expect(bidResponse.length).to.equal(0);
- });
-
- it('should return no bids if the response "price" is missing', function () {
- const serverResponse = {
- seatbid: [{
- bid: [{
- adm: '
'
- }]
- }]
- };
- const bidResponse = spec.interpretResponse({
- body: serverResponse
- }, {
- bidRequest
- });
- expect(bidResponse.length).to.equal(0);
- });
-
- it('should return a valid video bid response with just "adm"', function () {
- const serverResponse = {
- seatbid: [{
- bid: [{
- id: 1,
- adid: 123,
- crid: 2,
- price: 6.01,
- adm: '
',
- adomain: [
- 'verizonmedia.com'
- ],
- }]
- }],
- cur: 'USD'
- };
- const bidResponse = spec.interpretResponse({
- body: serverResponse
- }, {
- bidRequest
- });
- let o = {
- requestId: bidRequest.bidId,
- bidderCode: spec.code,
- cpm: serverResponse.seatbid[0].bid[0].price,
- creativeId: serverResponse.seatbid[0].bid[0].crid,
- vastXml: serverResponse.seatbid[0].bid[0].adm,
- width: 640,
- height: 480,
- mediaType: 'video',
- currency: 'USD',
- ttl: 300,
- netRevenue: true,
- adUnitCode: bidRequest.adUnitCode,
- renderer: (bidRequest.mediaTypes.video.context === 'outstream') ? newRenderer(bidRequest, bidResponse) : undefined,
- meta: {
- advertiserDomains: ['verizonmedia.com']
- }
- };
- expect(bidResponse).to.deep.equal(o);
- });
- // @abrowning14 check that banner DAP response is appended to o.ad + mediaType: 'banner'
- it('should return a valid DAP banner bid-response', function () {
- bidRequest = {
- mediaTypes: {
- banner: {
- sizes: [640, 480]
- }
- },
- params: {
- video: {
- display: 1
- }
- }
- }
- const serverResponse = {
- seatbid: [{
- bid: [{
- id: 1,
- adid: 123,
- crid: 2,
- price: 6.01,
- adm: '
DAP UNIT HERE
'
- }]
- }],
- cur: 'USD'
- };
- const bidResponse = spec.interpretResponse({
- body: serverResponse
- }, {
- bidRequest
- });
- expect(bidResponse.ad).to.equal('
DAP UNIT HERE
');
- expect(bidResponse.mediaType).to.equal('banner');
- expect(bidResponse.renderer).to.be.undefined;
- });
-
- it('should default ttl to 300', function () {
- const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: '
'}]}], cur: 'USD'};
- const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
- expect(bidResponse.ttl).to.equal(300);
- });
- it('should not allow ttl above 3601, default to 300', function () {
- bidRequest.params.video.ttl = 3601;
- const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: '
'}]}], cur: 'USD'};
- const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
- expect(bidResponse.ttl).to.equal(300);
- });
- it('should not allow ttl below 1, default to 300', function () {
- bidRequest.params.video.ttl = 0;
- const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: '
'}]}], cur: 'USD'};
- const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
- expect(bidResponse.ttl).to.equal(300);
- });
- it('should use custom ttl if under 3600', function () {
- bidRequest.params.video.ttl = 1000;
- const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: '
'}]}], cur: 'USD'};
- const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest });
- expect(bidResponse.ttl).to.equal(1000);
- });
- });
-
- describe('when GDPR and uspConsent applies', function () {
- beforeEach(function () {
- bidderRequest = {
- 'gdprConsent': {
- 'consentString': 'test-gdpr-consent-string',
- 'gdprApplies': true
- },
- 'uspConsent': '1YN-',
- 'bidderCode': 'oneVideo',
- 'auctionId': 'e158486f-8c7f-472f-94ce-b0cbfbb50ab4',
- 'bidderRequestId': '1e498b84fffc39',
- 'bids': bidRequest,
- 'auctionStart': 1520001292880,
- 'timeout': 3000,
- 'start': 1520001292884,
- 'doneCbCallCount': 0,
- 'refererInfo': {
- 'numIframes': 1,
- 'reachedTop': true,
- 'referer': 'test.com'
- }
- };
-
- mockConfig = {
- consentManagement: {
- gdpr: {
- cmpApi: 'iab',
- timeout: 3000,
- allowAuctionWithoutConsent: 'cancel'
- },
- usp: {
- cmpApi: 'iab',
- timeout: 1000,
- allowAuctionWithoutConsent: 'cancel'
- }
- }
- };
- });
-
- it('should send a signal to specify that GDPR applies to this request', function () {
- const request = spec.buildRequests([bidRequest], bidderRequest);
- expect(request[0].data.regs.ext.gdpr).to.equal(1);
- });
-
- it('should send the consent string', function () {
- const request = spec.buildRequests([bidRequest], bidderRequest);
- expect(request[0].data.user.ext.consent).to.equal(bidderRequest.gdprConsent.consentString);
- });
-
- it('should send the uspConsent string', function () {
- const request = spec.buildRequests([bidRequest], bidderRequest);
- expect(request[0].data.regs.ext.us_privacy).to.equal(bidderRequest.uspConsent);
- });
-
- it('should send the uspConsent and GDPR ', function () {
- const request = spec.buildRequests([bidRequest], bidderRequest);
- expect(request[0].data.regs.ext.gdpr).to.equal(1);
- expect(request[0].data.regs.ext.us_privacy).to.equal(bidderRequest.uspConsent);
- });
- });
-
- describe('should send banner object', function () {
- it('should send banner object when display is 1 and context="instream" (DAP O&O)', function () {
- bidRequest = {
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [640, 480]
- }
- },
- bidder: 'oneVideo',
- sizes: [640, 480],
- bidId: '30b3efwfwe1e',
- adUnitCode: 'video1',
- params: {
- video: {
- playerWidth: 640,
- playerHeight: 480,
- mimes: ['video/mp4', 'application/javascript'],
- protocols: [2, 5],
- api: [2],
- position: 1,
- delivery: [2],
- playbackmethod: [1, 5],
- placement: 1,
- inventoryid: 123,
- sid: 134,
- display: 1,
- minduration: 10,
- maxduration: 30
- },
- site: {
- id: 1,
- page: 'https://www.yahoo.com/',
- referrer: 'http://www.yahoo.com'
- },
- pubId: 'OneMDisplay'
- }
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const width = bidRequest.params.video.playerWidth;
- const height = bidRequest.params.video.playerHeight;
- const position = bidRequest.params.video.position;
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- expect(data.imp[0].banner.w).to.equal(width);
- expect(data.imp[0].banner.h).to.equal(height);
- expect(data.imp[0].banner.pos).to.equal(position);
- expect(data.imp[0].ext.inventoryid).to.equal(bidRequest.params.video.inventoryid);
- expect(data.imp[0].banner.mimes).to.equal(bidRequest.params.video.mimes);
- expect(data.imp[0].banner.placement).to.equal(bidRequest.params.video.placement);
- expect(data.imp[0].banner.ext.minduration).to.equal(bidRequest.params.video.minduration);
- expect(data.imp[0].banner.ext.maxduration).to.equal(bidRequest.params.video.maxduration);
- expect(data.site.id).to.equal(bidRequest.params.site.id);
- });
- it('should send video object when display is other than 1 (VAST for All)', function () {
- bidRequest = {
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [640, 480]
- }
- },
- bidder: 'oneVideo',
- sizes: [640, 480],
- bidId: '30b3efwfwe1e',
- adUnitCode: 'video1',
- params: {
- video: {
- playerWidth: 640,
- playerHeight: 480,
- mimes: ['video/mp4', 'application/javascript'],
- protocols: [2, 5],
- api: [2],
- position: 1,
- delivery: [2],
- playbackmethod: [1, 5],
- placement: 123,
- sid: 134,
- display: 12
- },
- site: {
- id: 1,
- page: 'https://www.yahoo.com/',
- referrer: 'http://www.yahoo.com'
- },
- pubId: 'OneMDisplay'
- }
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const width = bidRequest.params.video.playerWidth;
- const height = bidRequest.params.video.playerHeight;
- const position = bidRequest.params.video.position;
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- expect(data.imp[0].video.w).to.equal(width);
- expect(data.imp[0].video.h).to.equal(height);
- expect(data.imp[0].video.pos).to.equal(position);
- expect(data.imp[0].video.mimes).to.equal(bidRequest.params.video.mimes);
- });
- it('should send video object when display is not passed (VAST for All)', function () {
- bidRequest = {
- mediaTypes: {
- video: {
- context: 'instream',
- playerSize: [640, 480]
- }
- },
- bidder: 'oneVideo',
- sizes: [640, 480],
- bidId: '30b3efwfwe1e',
- adUnitCode: 'video1',
- params: {
- video: {
- playerWidth: 640,
- playerHeight: 480,
- mimes: ['video/mp4', 'application/javascript'],
- protocols: [2, 5],
- api: [2],
- position: 1,
- delivery: [2],
- playbackmethod: [1, 5],
- placement: 123,
- sid: 134,
- minduration: 10,
- maxduration: 30
- },
- site: {
- id: 1,
- page: 'https://www.yahoo.com/',
- referrer: 'http://www.yahoo.com'
- },
- pubId: 'OneMDisplay'
- }
- };
- const requests = spec.buildRequests([bidRequest], bidderRequest);
- const data = requests[0].data;
- const width = bidRequest.params.video.playerWidth;
- const height = bidRequest.params.video.playerHeight;
- const position = bidRequest.params.video.position;
- expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- expect(data.imp[0].video.w).to.equal(width);
- expect(data.imp[0].video.h).to.equal(height);
- expect(data.imp[0].video.pos).to.equal(position);
- expect(data.imp[0].video.mimes).to.equal(bidRequest.params.video.mimes);
- expect(data.imp[0].video.protocols).to.equal(bidRequest.params.video.protocols);
- expect(data.imp[0].video.linearity).to.equal(1);
- expect(data.imp[0].video.maxduration).to.equal(bidRequest.params.video.maxduration);
- expect(data.imp[0].video.minduration).to.equal(bidRequest.params.video.minduration);
- });
- describe('getUserSyncs', function () {
- const GDPR_CONSENT_STRING = 'GDPR_CONSENT_STRING';
-
- it('should get correct user sync when iframeEnabled', function () {
- let pixel = spec.getUserSyncs({
- pixelEnabled: true
- }, {}, {
- gdprApplies: true,
- consentString: GDPR_CONSENT_STRING
- })
- expect(pixel[1].type).to.equal('image');
- expect(pixel[1].url).to.equal('https://sync-tm.everesttech.net/upi/pid/m7y5t93k?gdpr=1&gdpr_consent=' + GDPR_CONSENT_STRING + '&redir=https%3A%2F%2Fpixel.advertising.com%2Fups%2F55986%2Fsync%3Fuid%3D%24%7BUSER_ID%7D%26_origin%3D0&gdpr=1&gdpr_consent=' + encodeURI(GDPR_CONSENT_STRING));
- });
-
- it('should default to gdprApplies=0 when consentData is undefined', function () {
- let pixel = spec.getUserSyncs({
- pixelEnabled: true
- }, {}, undefined);
- expect(pixel[1].url).to.equal('https://sync-tm.everesttech.net/upi/pid/m7y5t93k?gdpr=0&gdpr_consent=&redir=https%3A%2F%2Fpixel.advertising.com%2Fups%2F55986%2Fsync%3Fuid%3D%24%7BUSER_ID%7D%26_origin%3D0&gdpr=0&gdpr_consent=');
- });
- });
-
- describe('verify sync pixels', function () {
- let pixel = spec.getUserSyncs({
- pixelEnabled: true
- }, {}, undefined);
- it('should be UPS sync pixel for DBM', function () {
- expect(pixel[0].url).to.equal('https://pixel.advertising.com/ups/57304/sync?gdpr=&gdpr_consent=&_origin=0&redir=true')
- });
-
- it('should be TTD sync pixel', function () {
- expect(pixel[2].url).to.equal('https://match.adsrvr.org/track/cmf/generic?ttd_pid=adaptv&ttd_tpi=1')
- });
- })
- });
-});
diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js
index f335f2ec62a..2dc0a43bbb0 100644
--- a/test/spec/modules/onetagBidAdapter_spec.js
+++ b/test/spec/modules/onetagBidAdapter_spec.js
@@ -1,4 +1,4 @@
-import { spec, isValid, hasTypeVideo } from 'modules/onetagBidAdapter.js';
+import { spec, isValid, hasTypeVideo, isSchainValid } from 'modules/onetagBidAdapter.js';
import { expect } from 'chai';
import {find} from 'src/polyfill.js';
import { BANNER, VIDEO } from 'src/mediaTypes.js';
@@ -15,7 +15,21 @@ describe('onetag', function () {
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
- 'transactionId': 'qwerty123'
+ 'transactionId': 'qwerty123',
+ 'schain': {
+ 'validation': 'off',
+ 'config': {
+ 'ver': '1.0',
+ 'complete': 1,
+ 'nodes': [
+ {
+ 'asi': 'indirectseller.com',
+ 'sid': '00001',
+ 'hp': 1
+ }
+ ]
+ }
+ },
};
}
@@ -193,7 +207,8 @@ describe('onetag', function () {
'context',
'playerSize',
'mediaTypeInfo',
- 'type'
+ 'type',
+ 'priceFloors'
);
} else if (isValid(BANNER, bid)) {
expect(bid).to.have.all.keys(
@@ -205,9 +220,13 @@ describe('onetag', function () {
'transactionId',
'mediaTypeInfo',
'sizes',
- 'type'
+ 'type',
+ 'priceFloors'
);
}
+ if (bid.schain && isSchainValid(bid.schain)) {
+ expect(data).to.have.all.keys('schain');
+ }
expect(bid.bidId).to.be.a('string');
expect(bid.pubId).to.be.a('string');
}
@@ -358,6 +377,36 @@ describe('onetag', function () {
expect(syncs[0].url).to.match(/(?:[?&](?:us_privacy=us_foo(?:[&][^&]*)*))+$/);
});
});
+ describe('isSchainValid', function () {
+ it('Should return false when schain is null or undefined', function () {
+ expect(isSchainValid(null)).to.be.false;
+ expect(isSchainValid(undefined)).to.be.false;
+ });
+ it('Should return false when schain is missing nodes key', function () {
+ const schain = {'otherKey': 'otherValue'};
+ expect(isSchainValid(schain)).to.be.false;
+ });
+ it('Should return false when schain is missing one of the required SupplyChainNode attribute', function () {
+ const missingAsiNode = {'sid': '00001', 'hp': 1};
+ const missingSidNode = {'asi': 'indirectseller.com', 'hp': 1};
+ const missingHpNode = {'asi': 'indirectseller.com', 'sid': '00001'};
+ expect(isSchainValid({'config': {'nodes': [missingAsiNode]}})).to.be.false;
+ expect(isSchainValid({'config': {'nodes': [missingSidNode]}})).to.be.false;
+ expect(isSchainValid({'config': {'nodes': [missingHpNode]}})).to.be.false;
+ });
+ it('Should return true when schain contains all required attributes', function () {
+ const validSchain = {
+ 'nodes': [
+ {
+ 'asi': 'indirectseller.com',
+ 'sid': '00001',
+ 'hp': 1
+ }
+ ]
+ };
+ expect(isSchainValid(validSchain)).to.be.true;
+ })
+ });
});
function getBannerVideoResponse() {
diff --git a/test/spec/modules/openxAnalyticsAdapter_spec.js b/test/spec/modules/openxAnalyticsAdapter_spec.js
index 47663a41f47..1b1adeb8807 100644
--- a/test/spec/modules/openxAnalyticsAdapter_spec.js
+++ b/test/spec/modules/openxAnalyticsAdapter_spec.js
@@ -1,653 +1,21 @@
import { expect } from 'chai';
-import openxAdapter, {AUCTION_STATES} from 'modules/openxAnalyticsAdapter.js';
-import * as events from 'src/events.js';
-import CONSTANTS from 'src/constants.json';
+import openxAdapter from 'modules/openxAnalyticsAdapter.js';
import * as utils from 'src/utils.js';
-import { server } from 'test/mocks/xhr.js';
-import {find} from 'src/polyfill.js';
-
-const {
- EVENTS: { AUCTION_INIT, BID_REQUESTED, BID_RESPONSE, BID_TIMEOUT, BID_WON, AUCTION_END }
-} = CONSTANTS;
-const SLOT_LOADED = 'slotOnload';
-const CURRENT_TIME = 1586000000000;
describe('openx analytics adapter', function() {
- describe('when validating the configuration', function () {
+ describe('deprecation message', function () {
let spy;
beforeEach(function () {
- spy = sinon.spy(utils, 'logError');
+ spy = sinon.spy(utils, 'logWarn');
});
afterEach(function() {
- utils.logError.restore();
+ utils.logWarn.restore();
});
- it('should require organization id when no configuration is passed', function() {
+ it('should warn on enable', function() {
openxAdapter.enableAnalytics();
- expect(spy.firstCall.args[0]).to.match(/publisherPlatformId/);
- expect(spy.firstCall.args[0]).to.match(/to exist/);
- });
-
- it('should require publisher id when no orgId is passed', function() {
- openxAdapter.enableAnalytics({
- provider: 'openx',
- options: {
- publisherAccountId: 12345
- }
- });
- expect(spy.firstCall.args[0]).to.match(/publisherPlatformId/);
- expect(spy.firstCall.args[0]).to.match(/to exist/);
- });
-
- it('should validate types', function() {
- openxAdapter.enableAnalytics({
- provider: 'openx',
- options: {
- orgId: 'test platformId',
- sampling: 'invalid-float'
- }
- });
-
- expect(spy.firstCall.args[0]).to.match(/sampling/);
- expect(spy.firstCall.args[0]).to.match(/type 'number'/);
- });
- });
-
- describe('when tracking analytic events', function () {
- const AD_UNIT_CODE = 'test-div-1';
- const SLOT_LOAD_WAIT_TIME = 10;
-
- const DEFAULT_V2_ANALYTICS_CONFIG = {
- orgId: 'test-org-id',
- publisherAccountId: 123,
- publisherPlatformId: 'test-platform-id',
- configId: 'my_config',
- optimizerConfig: 'my my optimizer',
- sample: 1.0,
- payloadWaitTime: SLOT_LOAD_WAIT_TIME,
- payloadWaitTimePadding: SLOT_LOAD_WAIT_TIME
- };
-
- const auctionInit = {
- auctionId: 'test-auction-id',
- timestamp: CURRENT_TIME,
- timeout: 3000,
- adUnitCodes: [AD_UNIT_CODE],
- };
-
- const bidRequestedOpenX = {
- auctionId: 'test-auction-id',
- auctionStart: CURRENT_TIME,
- timeout: 2000,
- bids: [
- {
- adUnitCode: AD_UNIT_CODE,
- bidId: 'test-openx-request-id',
- bidder: 'openx',
- params: { unit: 'test-openx-ad-unit-id' },
- userId: {
- tdid: 'test-tradedesk-id',
- empty_id: '',
- null_id: null,
- bla_id: '',
- digitrustid: { data: { id: '1' } },
- lipbid: { lipb: '2' }
- }
- }
- ],
- start: CURRENT_TIME + 10
- };
-
- const bidRequestedCloseX = {
- auctionId: 'test-auction-id',
- auctionStart: CURRENT_TIME,
- timeout: 1000,
- bids: [
- {
- adUnitCode: AD_UNIT_CODE,
- bidId: 'test-closex-request-id',
- bidder: 'closex',
- params: { unit: 'test-closex-ad-unit-id' },
- userId: {
- bla_id: '2',
- tdid: 'test-tradedesk-id'
- }
- }
- ],
- start: CURRENT_TIME + 20
- };
-
- const bidResponseOpenX = {
- adUnitCode: AD_UNIT_CODE,
- cpm: 0.5,
- netRevenue: true,
- requestId: 'test-openx-request-id',
- mediaType: 'banner',
- width: 300,
- height: 250,
- adId: 'test-openx-ad-id',
- auctionId: 'test-auction-id',
- creativeId: 'openx-crid',
- currency: 'USD',
- timeToRespond: 100,
- responseTimestamp: CURRENT_TIME + 30,
- ts: 'test-openx-ts'
- };
-
- const bidResponseCloseX = {
- adUnitCode: AD_UNIT_CODE,
- cpm: 0.3,
- netRevenue: true,
- requestId: 'test-closex-request-id',
- mediaType: 'video',
- width: 300,
- height: 250,
- adId: 'test-closex-ad-id',
- auctionId: 'test-auction-id',
- creativeId: 'closex-crid',
- currency: 'USD',
- timeToRespond: 200,
- dealId: 'test-closex-deal-id',
- responseTimestamp: CURRENT_TIME + 40,
- ts: 'test-closex-ts'
- };
-
- const bidTimeoutOpenX = {
- 0: {
- adUnitCode: AD_UNIT_CODE,
- auctionId: 'test-auction-id',
- bidId: 'test-openx-request-id'
- }};
-
- const bidTimeoutCloseX = {
- 0: {
- adUnitCode: AD_UNIT_CODE,
- auctionId: 'test-auction-id',
- bidId: 'test-closex-request-id'
- }
- };
-
- const bidWonOpenX = {
- requestId: 'test-openx-request-id',
- adId: 'test-openx-ad-id',
- adUnitCode: AD_UNIT_CODE,
- auctionId: 'test-auction-id'
- };
-
- const auctionEnd = {
- auctionId: 'test-auction-id',
- timestamp: CURRENT_TIME,
- auctionEnd: CURRENT_TIME + 100,
- timeout: 3000,
- adUnitCodes: [AD_UNIT_CODE],
- };
-
- const bidWonCloseX = {
- requestId: 'test-closex-request-id',
- adId: 'test-closex-ad-id',
- adUnitCode: AD_UNIT_CODE,
- auctionId: 'test-auction-id'
- };
-
- function simulateAuction(events) {
- let highestBid;
-
- events.forEach(event => {
- const [eventType, args] = event;
- if (eventType === BID_RESPONSE) {
- highestBid = highestBid || args;
- if (highestBid.cpm < args.cpm) {
- highestBid = args;
- }
- }
-
- if (eventType === SLOT_LOADED) {
- const slotLoaded = {
- slot: {
- getAdUnitPath: () => {
- return '/12345678/test_ad_unit';
- },
- getSlotElementId: () => {
- return AD_UNIT_CODE;
- },
- getTargeting: (key) => {
- if (key === 'hb_adid') {
- return highestBid ? [highestBid.adId] : [];
- } else {
- return [];
- }
- }
- }
- };
- openxAdapter.track({ eventType, args: slotLoaded });
- } else {
- openxAdapter.track({ eventType, args });
- }
- });
- }
-
- let clock;
-
- beforeEach(function() {
- sinon.stub(events, 'getEvents').returns([]);
- clock = sinon.useFakeTimers(CURRENT_TIME);
- });
-
- afterEach(function() {
- events.getEvents.restore();
- clock.restore();
- });
-
- describe('when there is an auction', function () {
- let auction;
- let auction2;
- beforeEach(function () {
- openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG});
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [SLOT_LOADED]
- ]);
-
- simulateAuction([
- [AUCTION_INIT, {...auctionInit, auctionId: 'second-auction-id'}],
- [SLOT_LOADED]
- ]);
-
- clock.tick(SLOT_LOAD_WAIT_TIME);
- auction = JSON.parse(server.requests[0].requestBody)[0];
- auction2 = JSON.parse(server.requests[1].requestBody)[0];
- });
-
- afterEach(function () {
- openxAdapter.reset();
- openxAdapter.disableAnalytics();
- });
-
- it('should track auction start time', function () {
- expect(auction.startTime).to.equal(auctionInit.timestamp);
- });
-
- it('should track auction time limit', function () {
- expect(auction.timeLimit).to.equal(auctionInit.timeout);
- });
-
- it('should track the \'default\' test code', function () {
- expect(auction.testCode).to.equal('default');
- });
-
- it('should track auction count', function () {
- expect(auction.auctionOrder).to.equal(1);
- expect(auction2.auctionOrder).to.equal(2);
- });
-
- it('should track the orgId', function () {
- expect(auction.orgId).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.orgId);
- });
-
- it('should track the orgId', function () {
- expect(auction.publisherPlatformId).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.publisherPlatformId);
- });
-
- it('should track the orgId', function () {
- expect(auction.publisherAccountId).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.publisherAccountId);
- });
-
- it('should track the optimizerConfig', function () {
- expect(auction.optimizerConfig).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.optimizerConfig);
- });
-
- it('should track the configId', function () {
- expect(auction.configId).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.configId);
- });
-
- it('should track the auction Id', function () {
- expect(auction.auctionId).to.equal(auctionInit.auctionId);
- });
- });
-
- describe('when there is a custom test code', function () {
- let auction;
- beforeEach(function () {
- openxAdapter.enableAnalytics({
- options: {
- ...DEFAULT_V2_ANALYTICS_CONFIG,
- testCode: 'test-code'
- }
- });
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [SLOT_LOADED],
- ]);
- clock.tick(SLOT_LOAD_WAIT_TIME);
- auction = JSON.parse(server.requests[0].requestBody)[0];
- });
-
- afterEach(function () {
- openxAdapter.reset();
- openxAdapter.disableAnalytics();
- });
-
- it('should track the custom test code', function () {
- expect(auction.testCode).to.equal('test-code');
- });
- });
-
- describe('when there is campaign (utm) data', function () {
- let auction;
- beforeEach(function () {
-
- });
-
- afterEach(function () {
- openxAdapter.reset();
- utils.getWindowLocation.restore();
- openxAdapter.disableAnalytics();
- });
-
- it('should track values from query params when they exist', function () {
- sinon.stub(utils, 'getWindowLocation').returns({search: '?' +
- 'utm_campaign=test%20campaign-name&' +
- 'utm_source=test-source&' +
- 'utm_medium=test-medium&'
- });
-
- openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG});
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [SLOT_LOADED],
- ]);
- clock.tick(SLOT_LOAD_WAIT_TIME);
- auction = JSON.parse(server.requests[0].requestBody)[0];
-
- // ensure that value are URI decoded
- expect(auction.campaign.name).to.equal('test campaign-name');
- expect(auction.campaign.source).to.equal('test-source');
- expect(auction.campaign.medium).to.equal('test-medium');
- expect(auction.campaign.content).to.be.undefined;
- expect(auction.campaign.term).to.be.undefined;
- });
-
- it('should override query params if configuration parameters exist', function () {
- sinon.stub(utils, 'getWindowLocation').returns({search: '?' +
- 'utm_campaign=test-campaign-name&' +
- 'utm_source=test-source&' +
- 'utm_medium=test-medium&' +
- 'utm_content=test-content&' +
- 'utm_term=test-term'
- });
-
- openxAdapter.enableAnalytics({
- options: {
- ...DEFAULT_V2_ANALYTICS_CONFIG,
- campaign: {
- name: 'test-config-name',
- source: 'test-config-source',
- medium: 'test-config-medium'
- }
- }
- });
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [SLOT_LOADED],
- ]);
- clock.tick(SLOT_LOAD_WAIT_TIME);
- auction = JSON.parse(server.requests[0].requestBody)[0];
-
- expect(auction.campaign.name).to.equal('test-config-name');
- expect(auction.campaign.source).to.equal('test-config-source');
- expect(auction.campaign.medium).to.equal('test-config-medium');
- expect(auction.campaign.content).to.equal('test-content');
- expect(auction.campaign.term).to.equal('test-term');
- });
- });
-
- describe('when there are bid requests', function () {
- let auction;
- let openxBidder;
- let closexBidder;
-
- beforeEach(function () {
- openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG});
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [BID_REQUESTED, bidRequestedCloseX],
- [BID_REQUESTED, bidRequestedOpenX],
- [SLOT_LOADED],
- ]);
- clock.tick(SLOT_LOAD_WAIT_TIME * 2);
- auction = JSON.parse(server.requests[0].requestBody)[0];
- openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx');
- closexBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex');
- });
-
- afterEach(function () {
- openxAdapter.reset();
- openxAdapter.disableAnalytics();
- });
-
- it('should track the bidder', function () {
- expect(openxBidder.bidder).to.equal('openx');
- expect(closexBidder.bidder).to.equal('closex');
- });
-
- it('should track the adunit code', function () {
- expect(auction.adUnits[0].code).to.equal(AD_UNIT_CODE);
- });
-
- it('should track the user ids', function () {
- expect(auction.userIdProviders).to.deep.equal(['bla_id', 'digitrustid', 'lipbid', 'tdid']);
- });
-
- it('should not have responded', function () {
- expect(openxBidder.hasBidderResponded).to.equal(false);
- expect(closexBidder.hasBidderResponded).to.equal(false);
- });
- });
-
- describe('when there are request timeouts', function () {
- let auction;
- let openxBidRequest;
- let closexBidRequest;
-
- beforeEach(function () {
- openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG});
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [BID_REQUESTED, bidRequestedCloseX],
- [BID_REQUESTED, bidRequestedOpenX],
- [BID_TIMEOUT, bidTimeoutCloseX],
- [BID_TIMEOUT, bidTimeoutOpenX],
- [AUCTION_END, auctionEnd]
- ]);
- clock.tick(SLOT_LOAD_WAIT_TIME * 2);
- auction = JSON.parse(server.requests[0].requestBody)[0];
-
- openxBidRequest = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx');
- closexBidRequest = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex');
- });
-
- afterEach(function () {
- openxAdapter.reset();
- openxAdapter.disableAnalytics();
- });
-
- it('should track the timeout', function () {
- expect(openxBidRequest.timedOut).to.equal(true);
- expect(closexBidRequest.timedOut).to.equal(true);
- });
-
- it('should track the timeout value ie timeLimit', function () {
- expect(openxBidRequest.timeLimit).to.equal(2000);
- expect(closexBidRequest.timeLimit).to.equal(1000);
- });
- });
-
- describe('when there are bid responses', function () {
- let auction;
- let openxBidResponse;
- let closexBidResponse;
-
- beforeEach(function () {
- openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG});
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [BID_REQUESTED, bidRequestedCloseX],
- [BID_REQUESTED, bidRequestedOpenX],
- [BID_RESPONSE, bidResponseOpenX],
- [BID_RESPONSE, bidResponseCloseX],
- [AUCTION_END, auctionEnd]
- ]);
-
- clock.tick(SLOT_LOAD_WAIT_TIME * 2);
- auction = JSON.parse(server.requests[0].requestBody)[0];
-
- openxBidResponse = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx').bidResponses[0];
- closexBidResponse = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex').bidResponses[0];
- });
-
- afterEach(function () {
- openxAdapter.reset();
- openxAdapter.disableAnalytics();
- });
-
- it('should track the cpm in microCPM', function () {
- expect(openxBidResponse.microCpm).to.equal(bidResponseOpenX.cpm * 1000000);
- expect(closexBidResponse.microCpm).to.equal(bidResponseCloseX.cpm * 1000000);
- });
-
- it('should track if the bid is in net revenue', function () {
- expect(openxBidResponse.netRevenue).to.equal(bidResponseOpenX.netRevenue);
- expect(closexBidResponse.netRevenue).to.equal(bidResponseCloseX.netRevenue);
- });
-
- it('should track the mediaType', function () {
- expect(openxBidResponse.mediaType).to.equal(bidResponseOpenX.mediaType);
- expect(closexBidResponse.mediaType).to.equal(bidResponseCloseX.mediaType);
- });
-
- it('should track the currency', function () {
- expect(openxBidResponse.currency).to.equal(bidResponseOpenX.currency);
- expect(closexBidResponse.currency).to.equal(bidResponseCloseX.currency);
- });
-
- it('should track the ad width and height', function () {
- expect(openxBidResponse.width).to.equal(bidResponseOpenX.width);
- expect(openxBidResponse.height).to.equal(bidResponseOpenX.height);
-
- expect(closexBidResponse.width).to.equal(bidResponseCloseX.width);
- expect(closexBidResponse.height).to.equal(bidResponseCloseX.height);
- });
-
- it('should track the bid dealId', function () {
- expect(openxBidResponse.dealId).to.equal(bidResponseOpenX.dealId); // no deal id defined
- expect(closexBidResponse.dealId).to.equal(bidResponseCloseX.dealId); // deal id defined
- });
-
- it('should track the bid\'s latency', function () {
- expect(openxBidResponse.latency).to.equal(bidResponseOpenX.timeToRespond);
- expect(closexBidResponse.latency).to.equal(bidResponseCloseX.timeToRespond);
- });
-
- it('should not have any bid winners', function () {
- expect(openxBidResponse.winner).to.equal(false);
- expect(closexBidResponse.winner).to.equal(false);
- });
-
- it('should track the bid currency', function () {
- expect(openxBidResponse.currency).to.equal(bidResponseOpenX.currency);
- expect(closexBidResponse.currency).to.equal(bidResponseCloseX.currency);
- });
-
- it('should track the auction end time', function () {
- expect(auction.endTime).to.equal(auctionEnd.auctionEnd);
- });
-
- it('should track that the auction ended', function () {
- expect(auction.state).to.equal(AUCTION_STATES.ENDED);
- });
- });
-
- describe('when there are bidder wins', function () {
- let auction;
- beforeEach(function () {
- openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG});
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [BID_REQUESTED, bidRequestedOpenX],
- [BID_REQUESTED, bidRequestedCloseX],
- [BID_RESPONSE, bidResponseOpenX],
- [BID_RESPONSE, bidResponseCloseX],
- [AUCTION_END, auctionEnd],
- [BID_WON, bidWonOpenX]
- ]);
-
- clock.tick(SLOT_LOAD_WAIT_TIME * 2);
- auction = JSON.parse(server.requests[0].requestBody)[0];
- });
-
- afterEach(function () {
- openxAdapter.reset();
- openxAdapter.disableAnalytics();
- });
-
- it('should track that bidder as the winner', function () {
- let openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx');
- expect(openxBidder.bidResponses[0]).to.contain({winner: true});
- });
-
- it('should track that bidder as the losers', function () {
- let closexBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex');
- expect(closexBidder.bidResponses[0]).to.contain({winner: false});
- });
- });
-
- describe('when a winning bid renders', function () {
- let auction;
- beforeEach(function () {
- openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG});
-
- simulateAuction([
- [AUCTION_INIT, auctionInit],
- [BID_REQUESTED, bidRequestedOpenX],
- [BID_REQUESTED, bidRequestedCloseX],
- [BID_RESPONSE, bidResponseOpenX],
- [BID_RESPONSE, bidResponseCloseX],
- [AUCTION_END, auctionEnd],
- [BID_WON, bidWonOpenX],
- [SLOT_LOADED]
- ]);
-
- clock.tick(SLOT_LOAD_WAIT_TIME * 2);
- auction = JSON.parse(server.requests[0].requestBody)[0];
- });
-
- afterEach(function () {
- openxAdapter.reset();
- openxAdapter.disableAnalytics();
- });
-
- it('should track that winning bid rendered', function () {
- let openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx');
- expect(openxBidder.bidResponses[0]).to.contain({rendered: true});
- });
-
- it('should track that winning bid render time', function () {
- let openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx');
- expect(openxBidder.bidResponses[0]).to.contain({renderTime: CURRENT_TIME});
- });
-
- it('should track that the auction completed', function () {
- expect(auction.state).to.equal(AUCTION_STATES.COMPLETED);
- });
+ expect(spy.firstCall.args[0]).to.match(/OpenX Analytics has been deprecated/);
});
});
});
diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js
index 3bc53e30eb8..cc1c2d1e607 100644
--- a/test/spec/modules/openxBidAdapter_spec.js
+++ b/test/spec/modules/openxBidAdapter_spec.js
@@ -1093,7 +1093,6 @@ describe('OpenxAdapter', function () {
tapadId: '111-tapadid',
tdid: '1111-tdid',
uid2: {id: '1111-uid2'},
- flocId: {id: '12144', version: 'chrome.1.1'},
novatiq: {snowflake: '1111-novatiqid'},
admixerId: '1111-admixerid',
deepintentId: '1111-deepintentid',
@@ -1147,9 +1146,6 @@ describe('OpenxAdapter', function () {
case 'merkleId':
userIdValue = EXAMPLE_DATA_BY_ATTR.merkleId.id;
break;
- case 'flocId':
- userIdValue = EXAMPLE_DATA_BY_ATTR.flocId.id;
- break;
case 'uid2':
userIdValue = EXAMPLE_DATA_BY_ATTR.uid2.id;
break;
@@ -1713,21 +1709,10 @@ describe('OpenxAdapter', function () {
context('in ortb2.user.data', function () {
let bidRequests;
beforeEach(function () {
- let fpdConfig = t.config
- sinon
- .stub(config, 'getConfig')
- .withArgs(sinon.match(/^ortb2\.user\.data$|^ortb2\.site\.content\.data$/))
- .callsFake((key) => {
- return utils.deepAccess(fpdConfig, key);
- });
bidRequests = [{...bidRequest, ...t.request}];
});
- afterEach(function () {
- config.getConfig.restore();
- });
-
- const mockBidderRequest = {refererInfo: {}};
+ const mockBidderRequest = {refererInfo: {}, ortb2: t.config.ortb2};
it(`${t.name} for type ${name}`, function () {
const request = spec.buildRequests(bidRequests, mockBidderRequest)
expect(request.length).to.equal(1);
diff --git a/test/spec/modules/openxOrtbBidAdapter_spec.js b/test/spec/modules/openxOrtbBidAdapter_spec.js
new file mode 100644
index 00000000000..6d1e59da677
--- /dev/null
+++ b/test/spec/modules/openxOrtbBidAdapter_spec.js
@@ -0,0 +1,1448 @@
+import {expect} from 'chai';
+import {spec, REQUEST_URL, SYNC_URL, DEFAULT_PH} from 'modules/openxOrtbBidAdapter.js';
+import {newBidder} from 'src/adapters/bidderFactory.js';
+import {BANNER, VIDEO} from 'src/mediaTypes.js';
+import {config} from 'src/config.js';
+import * as utils from 'src/utils.js';
+
+const DEFAULT_SYNC = SYNC_URL + '?ph=' + DEFAULT_PH;
+
+describe('OpenxRtbAdapter', function () {
+ const adapter = newBidder(spec);
+
+ describe('inherited functions', function () {
+ it('exists and is a function', function () {
+ expect(adapter.callBids).to.exist.and.to.be.a('function');
+ });
+ });
+
+ describe('isBidRequestValid()', function () {
+ describe('when request is for a banner ad', function () {
+ let bannerBid;
+ beforeEach(function () {
+ 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', function () {
+ bannerBid.params = {'unit': '12345678'};
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
+ });
+
+ describe('when there is a delivery domain', function () {
+ beforeEach(function () {
+ bannerBid.params = {delDomain: 'test-delivery-domain'}
+ });
+
+ it('should return false when there is no ad unit id and size', function () {
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
+ });
+
+ it('should return true if there is an adunit id ', function () {
+ bannerBid.params.unit = '12345678';
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
+ });
+
+ it('should return true if there is no adunit id and sizes are defined', function () {
+ bannerBid.mediaTypes.banner.sizes = [720, 90];
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(true);
+ });
+
+ it('should return false if no sizes are defined ', function () {
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
+ });
+
+ it('should return false if sizes empty ', function () {
+ bannerBid.mediaTypes.banner.sizes = [];
+ expect(spec.isBidRequestValid(bannerBid)).to.equal(false);
+ });
+ });
+ });
+
+ describe('when request is for a multiformat ad', function () {
+ describe('and request config uses mediaTypes video and banner', () => {
+ const multiformatBid = {
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250]]
+ },
+ video: {
+ playerSize: [300, 250]
+ }
+ },
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e'
+ };
+ it('should return true multisize when required params found', function () {
+ expect(spec.isBidRequestValid(multiformatBid)).to.equal(true);
+ });
+ });
+ });
+
+ describe('when request is for a video ad', function () {
+ describe('and request config uses mediaTypes', () => {
+ const videoBidWithMediaTypes = {
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480]
+ }
+ },
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e'
+ };
+ it('should return true when required params found', function () {
+ expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(true);
+ });
+
+ it('should return false when required params are not passed', function () {
+ let videoBidWithMediaTypes = Object.assign({}, videoBidWithMediaTypes);
+ videoBidWithMediaTypes.params = {};
+ expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false);
+ });
+ });
+ describe('and request config uses both delDomain and platform', () => {
+ const videoBidWithDelDomainAndPlatform = {
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain',
+ platform: '1cabba9e-cafe-3665-beef-f00f00f00f00'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480]
+ }
+ },
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e'
+ };
+ it('should return true when required params found', function () {
+ expect(spec.isBidRequestValid(videoBidWithDelDomainAndPlatform)).to.equal(true);
+ });
+
+ it('should return false when required params are not passed', function () {
+ let videoBidWithMediaTypes = Object.assign({}, videoBidWithDelDomainAndPlatform);
+ videoBidWithMediaTypes.params = {};
+ expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false);
+ });
+ });
+ describe('and request config uses mediaType', () => {
+ const videoBidWithMediaType = {
+ 'bidder': 'openx',
+ 'params': {
+ 'unit': '12345678',
+ 'delDomain': 'test-del-domain'
+ },
+ 'adUnitCode': 'adunit-code',
+ 'mediaType': 'video',
+ 'sizes': [640, 480],
+ 'bidId': '30b31c1838de1e',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'auctionId': '1d1a030790a475',
+ 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e'
+ };
+ it('should return true when required params found', function () {
+ expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(true);
+ });
+
+ it('should return false when required params are not passed', function () {
+ let videoBidWithMediaType = Object.assign({}, videoBidWithMediaType);
+ delete videoBidWithMediaType.params;
+ videoBidWithMediaType.params = {};
+ expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(false);
+ });
+ });
+ });
+ });
+
+ describe('buildRequests()', function () {
+ let bidRequestsWithMediaTypes;
+ let bidRequestsWithPlatform;
+ let mockBidderRequest;
+
+ beforeEach(function () {
+ mockBidderRequest = {refererInfo: {}};
+
+ bidRequestsWithMediaTypes = [{
+ bidder: 'openx',
+ params: {
+ unit: '11',
+ delDomain: 'test-del-domain',
+ platform: '1cabba9e-cafe-3665-beef-f00f00f00f00',
+ },
+ adUnitCode: '/adunit-code/test-path',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1',
+ transactionId: 'test-transactionId-1',
+ ortb2Imp: {
+ ext: {
+ ae: 2
+ }
+ }
+ }, {
+ bidder: 'openx',
+ params: {
+ unit: '22',
+ delDomain: 'test-del-domain',
+ platform: '1cabba9e-cafe-3665-beef-f00f00f00f00',
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480]
+ }
+ },
+ bidId: 'test-bid-id-2',
+ bidderRequestId: 'test-bid-request-2',
+ auctionId: 'test-auction-2',
+ transactionId: 'test-transactionId-2'
+ }];
+ });
+
+ context('common requests checks', function() {
+ it('should send bid request to openx url via POST', function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].url).to.equal(REQUEST_URL);
+ expect(request[0].method).to.equal('POST');
+ });
+
+ it('should send delivery domain, if available', function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.ext.delDomain).to.equal(bidRequestsWithMediaTypes[0].params.delDomain);
+ expect(request[0].data.ext.platformId).to.be.undefined;
+ });
+
+ it('should send platform id, if available', function () {
+ bidRequestsWithMediaTypes[0].params.platform = '1cabba9e-cafe-3665-beef-f00f00f00f00';
+ bidRequestsWithMediaTypes[1].params.platform = '1cabba9e-cafe-3665-beef-f00f00f00f00';
+
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.ext.platform).to.equal(bidRequestsWithMediaTypes[0].params.platform);
+ expect(request[1].data.ext.platform).to.equal(bidRequestsWithMediaTypes[0].params.platform);
+ });
+
+ it('should send openx adunit codes', function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.imp[0].tagid).to.equal(bidRequestsWithMediaTypes[0].params.unit);
+ expect(request[1].data.imp[0].tagid).to.equal(bidRequestsWithMediaTypes[1].params.unit);
+ });
+
+ it('should send out custom params on bids that have customParams specified', function () {
+ const bidRequest = Object.assign({},
+ bidRequestsWithMediaTypes[0],
+ {
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain',
+ customParams: {'Test1': 'testval1+', 'test2': ['testval2/', 'testval3']}
+ }
+ }
+ );
+
+ mockBidderRequest.bids = [bidRequest];
+ const request = spec.buildRequests([bidRequest], mockBidderRequest);
+ expect(request[0].data.imp[0].ext.customParams).to.equal(bidRequest.params.customParams);
+ })
+
+ describe('floors', function () {
+ it('should send out custom floors on bids that have customFloors, no currency as account currency is used', function () {
+ const bidRequest = Object.assign({},
+ bidRequestsWithMediaTypes[0],
+ {
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain',
+ customFloor: 1.500
+ }
+ }
+ );
+
+ const request = spec.buildRequests([bidRequest], mockBidderRequest);
+ expect(request[0].data.imp[0].bidfloor).to.equal(bidRequest.params.customFloor);
+ expect(request[0].data.imp[0].bidfloorcur).to.equal(undefined);
+ });
+
+ context('with floors module', function () {
+ let adServerCurrencyStub;
+
+ beforeEach(function () {
+ adServerCurrencyStub = sinon
+ .stub(config, 'getConfig')
+ .withArgs('currency.adServerCurrency')
+ });
+
+ afterEach(function () {
+ config.getConfig.restore();
+ });
+
+ it('should send out floors on bids in USD', function () {
+ const bidRequest = Object.assign({},
+ bidRequestsWithMediaTypes[0],
+ {
+ getFloor: () => {
+ return {
+ currency: 'USD',
+ floor: 9.99
+ }
+ }
+ }
+ );
+
+ const request = spec.buildRequests([bidRequest], mockBidderRequest);
+ expect(request[0].data.imp[0].bidfloor).to.equal(9.99);
+ expect(request[0].data.imp[0].bidfloorcur).to.equal('USD');
+ });
+
+ it('should send not send floors', function () {
+ adServerCurrencyStub.returns('EUR');
+ const bidRequest = Object.assign({},
+ bidRequestsWithMediaTypes[0],
+ {
+ getFloor: () => {
+ return {
+ currency: 'BTC',
+ floor: 9.99
+ }
+ }
+ }
+ );
+
+ const request = spec.buildRequests([bidRequest], mockBidderRequest);
+ expect(request[0].data.imp[0].bidfloor).to.equal(undefined)
+ expect(request[0].data.imp[0].bidfloorcur).to.equal(undefined)
+ });
+ })
+ })
+
+ describe('FPD', function() {
+ let bidRequests;
+ const mockBidderRequest = {refererInfo: {}};
+
+ beforeEach(function () {
+ bidRequests = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678-banner',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id',
+ transactionId: 'test-transaction-id-1'
+ }, {
+ bidder: 'openx',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480]
+ }
+ },
+ params: {
+ unit: '12345678-video',
+ delDomain: 'test-del-domain'
+ },
+ 'adUnitCode': 'adunit-code',
+
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id',
+ transactionId: 'test-transaction-id-2'
+ }];
+ });
+
+ it('ortb2.site should be merged in the request', function() {
+ const request = spec.buildRequests(bidRequests, {
+ ...mockBidderRequest,
+ 'ortb2': {
+ site: {
+ domain: 'page.example.com',
+ cat: ['IAB2'],
+ sectioncat: ['IAB2-2']
+ }
+ }
+ });
+ let data = request[0].data;
+ expect(data.site.domain).to.equal('page.example.com');
+ expect(data.site.cat).to.deep.equal(['IAB2']);
+ expect(data.site.sectioncat).to.deep.equal(['IAB2-2']);
+ });
+
+ it('ortb2.user should be merged in the request', function() {
+ const request = spec.buildRequests(bidRequests, {
+ ...mockBidderRequest,
+ 'ortb2': {
+ user: {
+ yob: 1985
+ }
+ }
+ });
+ let data = request[0].data;
+ expect(data.user.yob).to.equal(1985);
+ });
+
+ describe('ortb2Imp', function() {
+ describe('ortb2Imp.ext.data.pbadslot', function() {
+ beforeEach(function () {
+ if (bidRequests[0].hasOwnProperty('ortb2Imp')) {
+ delete bidRequests[0].ortb2Imp;
+ }
+ });
+
+ it('should not send if imp[].ext.data object is invalid', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {}
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ expect(data.imp[0].ext).to.not.have.property('data');
+ });
+
+ it('should not send if imp[].ext.data.pbadslot is undefined', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {
+ data: {
+ }
+ }
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ if (data.imp[0].ext.data) {
+ expect(data.imp[0].ext.data).to.not.have.property('pbadslot');
+ } else {
+ expect(data.imp[0].ext).to.not.have.property('data');
+ }
+ });
+
+ it('should send if imp[].ext.data.pbadslot is string', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {
+ data: {
+ pbadslot: 'abcd'
+ }
+ }
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ expect(data.imp[0].ext.data).to.have.property('pbadslot');
+ expect(data.imp[0].ext.data.pbadslot).to.equal('abcd');
+ });
+ });
+
+ describe('ortb2Imp.ext.data.adserver', function() {
+ beforeEach(function () {
+ if (bidRequests[0].hasOwnProperty('ortb2Imp')) {
+ delete bidRequests[0].ortb2Imp;
+ }
+ });
+
+ it('should not send if imp[].ext.data object is invalid', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {}
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ expect(data.imp[0].ext).to.not.have.property('data');
+ });
+
+ it('should not send if imp[].ext.data.adserver is undefined', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {
+ data: {
+ }
+ }
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ if (data.imp[0].ext.data) {
+ expect(data.imp[0].ext.data).to.not.have.property('adserver');
+ } else {
+ expect(data.imp[0].ext).to.not.have.property('data');
+ }
+ });
+
+ it('should send', function() {
+ let adSlotValue = 'abc';
+ bidRequests[0].ortb2Imp = {
+ ext: {
+ data: {
+ adserver: {
+ name: 'GAM',
+ adslot: adSlotValue
+ }
+ }
+ }
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ expect(data.imp[0].ext.data.adserver.name).to.equal('GAM');
+ expect(data.imp[0].ext.data.adserver.adslot).to.equal(adSlotValue);
+ });
+ });
+
+ describe('ortb2Imp.ext.data.other', function() {
+ beforeEach(function () {
+ if (bidRequests[0].hasOwnProperty('ortb2Imp')) {
+ delete bidRequests[0].ortb2Imp;
+ }
+ });
+
+ it('should not send if imp[].ext.data object is invalid', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {}
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ expect(data.imp[0].ext).to.not.have.property('data');
+ });
+
+ it('should not send if imp[].ext.data.other is undefined', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {
+ data: {
+ }
+ }
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ if (data.imp[0].ext.data) {
+ expect(data.imp[0].ext.data).to.not.have.property('other');
+ } else {
+ expect(data.imp[0].ext).to.not.have.property('data');
+ }
+ });
+
+ it('ortb2Imp.ext.data.other', function() {
+ bidRequests[0].ortb2Imp = {
+ ext: {
+ data: {
+ other: 1234
+ }
+ }
+ };
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ let data = request[0].data;
+ expect(data.imp[0].ext.data.other).to.equal(1234);
+ });
+ });
+ });
+ });
+
+ context('when there is a consent management framework', function () {
+ let bidRequests;
+ let mockConfig;
+ let bidderRequest;
+
+ beforeEach(function () {
+ bidRequests = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678-banner',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id',
+ transactionId: 'test-transaction-id-1'
+ }, {
+ bidder: 'openx',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480]
+ }
+ },
+ params: {
+ unit: '12345678-video',
+ delDomain: 'test-del-domain'
+ },
+ 'adUnitCode': 'adunit-code',
+
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id',
+ transactionId: 'test-transaction-id-2'
+ }];
+ });
+
+ describe('us_privacy', function () {
+ beforeEach(function () {
+ bidderRequest = {
+ uspConsent: '1YYN',
+ refererInfo: {}
+ };
+
+ sinon.stub(config, 'getConfig').callsFake((key) => {
+ return utils.deepAccess(mockConfig, key);
+ });
+ });
+
+ afterEach(function () {
+ config.getConfig.restore();
+ });
+
+ it('should send a signal to specify that US Privacy applies to this request', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.regs.ext.us_privacy).to.equal('1YYN');
+ expect(request[1].data.regs.ext.us_privacy).to.equal('1YYN');
+ });
+
+ it('should not send the regs object, when consent string is undefined', function () {
+ delete bidderRequest.uspConsent;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.regs).to.not.have.property('ext');
+ });
+ });
+
+ describe('GDPR', function () {
+ beforeEach(function () {
+ bidderRequest = {
+ gdprConsent: {
+ consentString: 'test-gdpr-consent-string',
+ addtlConsent: 'test-addtl-consent-string',
+ gdprApplies: true
+ },
+ refererInfo: {}
+ };
+
+ mockConfig = {
+ consentManagement: {
+ cmpApi: 'iab',
+ timeout: 1111,
+ allowAuctionWithoutConsent: 'cancel'
+ }
+ };
+
+ sinon.stub(config, 'getConfig').callsFake((key) => {
+ return utils.deepAccess(mockConfig, key);
+ });
+ });
+
+ afterEach(function () {
+ config.getConfig.restore();
+ });
+
+ it('should send a signal to specify that GDPR applies to this request', function () {
+ bidderRequest.bids = bidRequests;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.regs.ext.gdpr).to.equal(1);
+ expect(request[1].data.regs.ext.gdpr).to.equal(1);
+ });
+
+ it('should send the consent string', function () {
+ bidderRequest.bids = bidRequests;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.user.ext.consent).to.equal(bidderRequest.gdprConsent.consentString);
+ expect(request[1].data.user.ext.consent).to.equal(bidderRequest.gdprConsent.consentString);
+ });
+
+ it('should send the addtlConsent string', function () {
+ bidderRequest.bids = bidRequests;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.user.ext.ConsentedProvidersSettings.consented_providers).to.equal(bidderRequest.gdprConsent.addtlConsent);
+ expect(request[1].data.user.ext.ConsentedProvidersSettings.consented_providers).to.equal(bidderRequest.gdprConsent.addtlConsent);
+ });
+
+ it('should send a signal to specify that GDPR does not apply to this request', function () {
+ bidderRequest.gdprConsent.gdprApplies = false;
+ bidderRequest.bids = bidRequests;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.regs.ext.gdpr).to.equal(0);
+ expect(request[1].data.regs.ext.gdpr).to.equal(0);
+ });
+
+ it('when GDPR application is undefined, should not send a signal to specify whether GDPR applies to this request, ' +
+ 'but can send consent data, ', function () {
+ delete bidderRequest.gdprConsent.gdprApplies;
+ bidderRequest.bids = bidRequests;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.regs).to.not.have.property('ext');
+ expect(request[1].data.regs).to.not.have.property('ext');
+ expect(request[0].data.user.ext.consent).to.equal(bidderRequest.gdprConsent.consentString);
+ expect(request[1].data.user.ext.consent).to.equal(bidderRequest.gdprConsent.consentString);
+ });
+
+ it('when consent string is undefined, should not send the consent string, ', function () {
+ delete bidderRequest.gdprConsent.consentString;
+ bidderRequest.bids = bidRequests;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.imp[0].ext.consent).to.equal(undefined);
+ expect(request[1].data.imp[0].ext.consent).to.equal(undefined);
+ });
+ });
+ });
+
+ context('coppa', function() {
+ it('when there are no coppa param settings, should not send a coppa flag', function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.regs.coppa).to.equal(0);
+ });
+
+ it('should send a coppa flag there is when there is coppa param settings in the bid requests', function () {
+ let mockConfig = {
+ coppa: true
+ };
+
+ sinon.stub(config, 'getConfig').callsFake((key) => {
+ return utils.deepAccess(mockConfig, key);
+ });
+
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.regs.coppa).to.equal(1);
+ });
+
+ after(function () {
+ config.getConfig.restore()
+ });
+ });
+
+ context('do not track (DNT)', function() {
+ let doNotTrackStub;
+
+ beforeEach(function () {
+ doNotTrackStub = sinon.stub(utils, 'getDNT');
+ });
+ afterEach(function() {
+ doNotTrackStub.restore();
+ });
+
+ it('when there is a do not track, should send a dnt', function () {
+ doNotTrackStub.returns(1);
+
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.device.dnt).to.equal(1);
+ });
+
+ it('when there is not do not track, don\'t send dnt', function () {
+ doNotTrackStub.returns(0);
+
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.device.dnt).to.equal(0);
+ });
+
+ it('when there is no defined do not track, don\'t send dnt', function () {
+ doNotTrackStub.returns(null);
+
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.device.dnt).to.equal(0);
+ });
+ });
+
+ context('supply chain (schain)', function () {
+ let bidRequests;
+ let schainConfig;
+ const supplyChainNodePropertyOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain'];
+
+ beforeEach(function () {
+ schainConfig = {
+ ver: '1.0',
+ complete: 1,
+ nodes: [
+ {
+ asi: 'exchange1.com',
+ sid: '1234',
+ hp: 1,
+ rid: 'bid-request-1',
+ name: 'publisher',
+ domain: 'publisher.com'
+ // omitted ext
+ },
+ {
+ asi: 'exchange2.com',
+ sid: 'abcd',
+ hp: 1,
+ rid: 'bid-request-2',
+ // name field missing
+ domain: 'intermediary.com'
+ },
+ {
+ asi: 'exchange3.com',
+ sid: '4321',
+ hp: 1,
+ // request id
+ // name field missing
+ domain: 'intermediary-2.com'
+ }
+ ]
+ };
+
+ bidRequests = [{
+ bidder: 'openx',
+ params: {
+ unit: '11',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: '/adunit-code/test-path',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1',
+ schain: schainConfig
+ }];
+ });
+
+ it('should send a supply chain object', function () {
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ expect(request[0].data.source.ext.schain).to.equal(schainConfig);
+ });
+
+ it('should send the supply chain object with the right version', function () {
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ expect(request[0].data.source.ext.schain.ver).to.equal(schainConfig.ver);
+ });
+
+ it('should send the supply chain object with the right complete value', function () {
+ const request = spec.buildRequests(bidRequests, mockBidderRequest);
+ expect(request[0].data.source.ext.schain.complete).to.equal(schainConfig.complete);
+ });
+ });
+
+ context('when there are userid providers', function () {
+ const userIdAsEids = [
+ {
+ source: 'adserver.org',
+ uids: [{
+ id: 'some-random-id-value',
+ atype: 1,
+ ext: {
+ rtiPartner: 'TDID'
+ }
+ }]
+ },
+ {
+ source: 'id5-sync.com',
+ uids: [{
+ id: 'some-random-id-value',
+ atype: 1
+ }]
+ },
+ {
+ source: 'sharedid.org',
+ uids: [{
+ id: 'some-random-id-value',
+ atype: 1,
+ ext: {
+ third: 'some-random-id-value'
+ }
+ }]
+ }
+ ];
+
+ it(`should send the user id under the extended ids`, function () {
+ const bidRequestsWithUserId = [{
+ bidder: 'openx',
+ params: {
+ unit: '11',
+ delDomain: 'test-del-domain'
+ },
+ userId: {
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ },
+ bidId: 'test-bid-id-1',
+ bidderRequestId: 'test-bid-request-1',
+ auctionId: 'test-auction-1',
+ userIdAsEids: userIdAsEids
+ }];
+ // enrich bid request with userId key/value
+
+ const request = spec.buildRequests(bidRequestsWithUserId, mockBidderRequest);
+ expect(request[0].data.user.ext.eids).to.equal(userIdAsEids);
+ });
+
+ it(`when no user ids are available, it should not send any extended ids`, function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data).to.not.have.any.keys('user');
+ });
+ });
+
+ context('FLEDGE', function() {
+ it('when FLEDGE is disabled, should not send imp.ext.ae', function () {
+ const request = spec.buildRequests(
+ bidRequestsWithMediaTypes,
+ {
+ ...mockBidderRequest,
+ fledgeEnabled: false
+ }
+ );
+ expect(request[0].data.imp[0].ext).to.not.have.property('ae');
+ });
+
+ it('when FLEDGE is enabled, should send whatever is set in ortb2imp.ext.ae in all bid requests', function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, {
+ ...mockBidderRequest,
+ fledgeEnabled: true
+ });
+ expect(request[0].data.imp[0].ext.ae).to.equal(2);
+ });
+ });
+ });
+
+ context('banner', function () {
+ it('should send bid request with a mediaTypes specified with banner type', function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[0].data.imp[0]).to.have.any.keys(BANNER);
+ });
+ });
+
+ context('video', function () {
+ it('should send bid request with a mediaTypes specified with video type', function () {
+ const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest);
+ expect(request[1].data.imp[0]).to.have.any.keys(VIDEO);
+ });
+ });
+
+ it.skip('should send ad unit ids when any are defined', function () {
+ const bidRequestsWithUnitIds = [{
+ 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',
+ transactionId: 'test-transaction-id-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',
+ transactionId: 'test-transaction-id-2'
+ }];
+ mockBidderRequest.bids = bidRequestsWithUnitIds;
+ const request = spec.buildRequests(bidRequestsWithUnitIds, mockBidderRequest);
+ expect(request[0].data.imp[1].tagid).to.equal(bidRequestsWithUnitIds[1].params.unit);
+ expect(request[0].data.imp[1].ext.divid).to.equal(bidRequestsWithUnitIds[1].params.adUnitCode);
+ });
+ });
+
+ describe('interpretResponse()', function () {
+ let bidRequestConfigs;
+ let bidRequest;
+ let bidResponse;
+ let bid;
+
+ context('when there is an nbr response', function () {
+ let bids;
+ beforeEach(function () {
+ bidRequestConfigs = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]],
+ },
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id'
+ }];
+
+ bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0];
+
+ bidResponse = {nbr: 0}; // Unknown error
+ bids = spec.interpretResponse({body: bidResponse}, bidRequest);
+ });
+
+ it('should not return any bids', function () {
+ expect(bids.length).to.equal(0);
+ });
+ });
+
+ context('when there is no response', function () {
+ let bids;
+ beforeEach(function () {
+ bidRequestConfigs = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]],
+ },
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id'
+ }];
+
+ bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0];
+
+ bidResponse = ''; // Unknown error
+ bids = spec.interpretResponse({body: bidResponse}, bidRequest);
+ });
+
+ it('should not return any bids', function () {
+ expect(bids.length).to.equal(0);
+ });
+ });
+
+ context('when there is a response, the common response properties', function () {
+ beforeEach(function () {
+ bidRequestConfigs = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]],
+ },
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id'
+ }];
+
+ bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0];
+
+ bidResponse = {
+ seatbid: [{
+ bid: [{
+ impid: 'test-bid-id',
+ price: 2,
+ w: 300,
+ h: 250,
+ crid: 'test-creative-id',
+ dealid: 'test-deal-id',
+ adm: 'test-ad-markup',
+ adomain: ['brand.com'],
+ ext: {
+ dsp_id: '123',
+ buyer_id: '456',
+ brand_id: '789',
+ paf: {
+ content_id: 'paf_content_id'
+ }
+ }
+ }]
+ }],
+ cur: 'AUS',
+ ext: {
+ paf: {
+ transmission: {version: '12'}
+ }
+ }
+ };
+
+ bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0];
+ });
+
+ it('should return a price', function () {
+ expect(bid.cpm).to.equal(bidResponse.seatbid[0].bid[0].price);
+ });
+
+ it('should return a request id', function () {
+ expect(bid.requestId).to.equal(bidResponse.seatbid[0].bid[0].impid);
+ });
+
+ it('should return width and height for the creative', function () {
+ expect(bid.width).to.equal(bidResponse.seatbid[0].bid[0].w);
+ expect(bid.height).to.equal(bidResponse.seatbid[0].bid[0].h);
+ });
+
+ it('should return a creativeId', function () {
+ expect(bid.creativeId).to.equal(bidResponse.seatbid[0].bid[0].crid);
+ });
+
+ it('should return an ad', function () {
+ expect(bid.ad).to.equal(bidResponse.seatbid[0].bid[0].adm);
+ });
+
+ it('should return a deal id if it exists', function () {
+ expect(bid.dealId).to.equal(bidResponse.seatbid[0].bid[0].dealid);
+ });
+
+ it('should have a time-to-live of 5 minutes', function () {
+ expect(bid.ttl).to.equal(300);
+ });
+
+ it('should always return net revenue', function () {
+ expect(bid.netRevenue).to.equal(true);
+ });
+
+ it('should return a currency', function () {
+ expect(bid.currency).to.equal(bidResponse.cur);
+ });
+
+ it('should return a brand ID', function () {
+ expect(bid.meta.brandId).to.equal(bidResponse.seatbid[0].bid[0].ext.brand_id);
+ });
+
+ it('should return a dsp ID', function () {
+ expect(bid.meta.networkId).to.equal(bidResponse.seatbid[0].bid[0].ext.dsp_id);
+ });
+
+ it('should return a buyer ID', function () {
+ expect(bid.meta.advertiserId).to.equal(bidResponse.seatbid[0].bid[0].ext.buyer_id);
+ });
+
+ it('should return adomain', function () {
+ expect(bid.meta.advertiserDomains).to.equal(bidResponse.seatbid[0].bid[0].adomain);
+ });
+
+ it('should return paf fields', function () {
+ const paf = {
+ transmission: {version: '12'},
+ content_id: 'paf_content_id'
+ }
+ expect(bid.meta.paf).to.deep.equal(paf);
+ });
+ });
+
+ context('when the response is a banner', function() {
+ beforeEach(function () {
+ bidRequestConfigs = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]],
+ },
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id'
+ }];
+
+ bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0];
+
+ bidResponse = {
+ seatbid: [{
+ bid: [{
+ impid: 'test-bid-id',
+ price: 2,
+ w: 300,
+ h: 250,
+ crid: 'test-creative-id',
+ dealid: 'test-deal-id',
+ adm: 'test-ad-markup'
+ }]
+ }],
+ cur: 'AUS'
+ };
+
+ bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0];
+ });
+
+ it('should return the proper mediaType', function () {
+ it('should return a creativeId', function () {
+ expect(bid.mediaType).to.equal(Object.keys(bidRequestConfigs[0].mediaTypes)[0]);
+ });
+ });
+ });
+
+ context('when the response is a video', function() {
+ beforeEach(function () {
+ bidRequestConfigs = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ video: {
+ playerSize: [[640, 360], [854, 480]],
+ },
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id'
+ }];
+
+ bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0];
+
+ bidResponse = {
+ seatbid: [{
+ bid: [{
+ impid: 'test-bid-id',
+ price: 2,
+ w: 854,
+ h: 480,
+ crid: 'test-creative-id',
+ dealid: 'test-deal-id',
+ adm: 'test-ad-markup',
+ }]
+ }],
+ cur: 'AUS'
+ };
+ });
+
+ it('should return the proper mediaType', function () {
+ bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0];
+ expect(bid.mediaType).to.equal(Object.keys(bidRequestConfigs[0].mediaTypes)[0]);
+ });
+
+ it('should return the proper mediaType', function () {
+ const winUrl = 'https//my.win.url';
+ bidResponse.seatbid[0].bid[0].nurl = winUrl
+ bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0];
+
+ expect(bid.vastUrl).to.equal(winUrl);
+ });
+ });
+
+ context('when the response contains FLEDGE interest groups config', function() {
+ let response;
+
+ beforeEach(function () {
+ sinon.stub(config, 'getConfig')
+ .withArgs('fledgeEnabled')
+ .returns(true);
+
+ bidRequestConfigs = [{
+ bidder: 'openx',
+ params: {
+ unit: '12345678',
+ delDomain: 'test-del-domain'
+ },
+ adUnitCode: 'adunit-code',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]],
+ },
+ },
+ bidId: 'test-bid-id',
+ bidderRequestId: 'test-bidder-request-id',
+ auctionId: 'test-auction-id'
+ }];
+
+ bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0];
+
+ bidResponse = {
+ seatbid: [{
+ bid: [{
+ impid: 'test-bid-id',
+ price: 2,
+ w: 300,
+ h: 250,
+ crid: 'test-creative-id',
+ dealid: 'test-deal-id',
+ adm: 'test-ad-markup'
+ }]
+ }],
+ cur: 'AUS',
+ ext: {
+ fledge_auction_configs: {
+ 'test-bid-id': {
+ seller: 'codinginadtech.com',
+ interestGroupBuyers: ['somedomain.com'],
+ sellerTimeout: 0,
+ perBuyerSignals: {
+ 'somedomain.com': {
+ base_bid_micros: 0.1,
+ disallowed_advertiser_ids: [
+ '1234',
+ '2345'
+ ],
+ multiplier: 1.3,
+ use_bid_multiplier: true,
+ win_reporting_id: '1234567asdf'
+ }
+ }
+ }
+ }
+ }
+ };
+
+ response = spec.interpretResponse({body: bidResponse}, bidRequest);
+ });
+
+ afterEach(function () {
+ config.getConfig.restore();
+ });
+
+ it('should return FLEDGE auction_configs alongside bids', function () {
+ expect(response).to.have.property('bids');
+ expect(response).to.have.property('fledgeAuctionConfigs');
+ expect(response.fledgeAuctionConfigs.length).to.equal(1);
+ expect(response.fledgeAuctionConfigs[0].bidId).to.equal('test-bid-id');
+ });
+ });
+ });
+
+ describe('user sync', function () {
+ it('should register the default image pixel if no pixels available', function () {
+ let syncs = spec.getUserSyncs(
+ {pixelEnabled: true},
+ []
+ );
+ expect(syncs).to.deep.equal([{type: 'image', url: DEFAULT_SYNC}]);
+ });
+
+ it('should register custom syncUrl when exists', function () {
+ let syncs = spec.getUserSyncs(
+ {pixelEnabled: true},
+ [{body: {ext: {delDomain: 'www.url.com'}}}]
+ );
+ expect(syncs).to.deep.equal([{type: 'image', url: 'https://www.url.com/w/1.0/pd'}]);
+ });
+
+ it('should register custom syncUrl when exists', function () {
+ let syncs = spec.getUserSyncs(
+ {pixelEnabled: true},
+ [{body: {ext: {platform: 'abc'}}}]
+ );
+ expect(syncs).to.deep.equal([{type: 'image', url: SYNC_URL + '?ph=abc'}]);
+ });
+
+ it('when iframe sync is allowed, it should register an iframe sync', function () {
+ let syncs = spec.getUserSyncs(
+ {iframeEnabled: true},
+ []
+ );
+ expect(syncs).to.deep.equal([{type: 'iframe', url: DEFAULT_SYNC}]);
+ });
+
+ it('should prioritize iframe over image for user sync', function () {
+ let syncs = spec.getUserSyncs(
+ {iframeEnabled: true, pixelEnabled: true},
+ []
+ );
+ expect(syncs).to.deep.equal([{type: 'iframe', url: DEFAULT_SYNC}]);
+ });
+
+ describe('when gdpr applies', function () {
+ let gdprConsent;
+ let gdprPixelUrl;
+ const consentString = 'gdpr-pixel-consent';
+ const gdprApplies = '1';
+ beforeEach(() => {
+ gdprConsent = {
+ consentString,
+ gdprApplies: true
+ };
+
+ gdprPixelUrl = `${SYNC_URL}&gdpr=${gdprApplies}&gdpr_consent=${consentString}`;
+ });
+
+ it('when there is a response, it should have the gdpr query params', () => {
+ let [{url}] = spec.getUserSyncs(
+ {iframeEnabled: true, pixelEnabled: true},
+ [],
+ gdprConsent
+ );
+
+ expect(url).to.have.string(`gdpr_consent=${consentString}`);
+ expect(url).to.have.string(`gdpr=${gdprApplies}`);
+ });
+
+ it('should not send signals if no consent object is available', function () {
+ let [{url}] = spec.getUserSyncs(
+ {iframeEnabled: true, pixelEnabled: true},
+ [],
+ );
+ expect(url).to.not.have.string('gdpr_consent=');
+ expect(url).to.not.have.string('gdpr=');
+ });
+ });
+
+ describe('when ccpa applies', function () {
+ let usPrivacyConsent;
+ let uspPixelUrl;
+ const privacyString = 'TEST';
+ beforeEach(() => {
+ usPrivacyConsent = 'TEST';
+ uspPixelUrl = `${DEFAULT_SYNC}&us_privacy=${privacyString}`
+ });
+ it('should send the us privacy string, ', () => {
+ let [{url}] = spec.getUserSyncs(
+ {iframeEnabled: true, pixelEnabled: true},
+ [],
+ undefined,
+ usPrivacyConsent
+ );
+ expect(url).to.have.string(`us_privacy=${privacyString}`);
+ });
+
+ it('should not send signals if no consent string is available', function () {
+ let [{url}] = spec.getUserSyncs(
+ {iframeEnabled: true, pixelEnabled: true},
+ [],
+ );
+ expect(url).to.not.have.string('us_privacy=');
+ });
+ });
+ });
+})
+;
diff --git a/test/spec/modules/operaadsBidAdapter_spec.js b/test/spec/modules/operaadsBidAdapter_spec.js
index 849a3eada3f..45bc8995a5c 100644
--- a/test/spec/modules/operaadsBidAdapter_spec.js
+++ b/test/spec/modules/operaadsBidAdapter_spec.js
@@ -49,7 +49,7 @@ describe('Opera Ads Bid Adapter', function () {
bidderCode: 'myBidderCode',
bidderRequestId: '15246a574e859f',
refererInfo: {
- referer: 'http://example.com',
+ page: 'http://example.com',
stack: ['http://example.com']
},
gdprConsent: {
@@ -242,7 +242,7 @@ describe('Opera Ads Bid Adapter', function () {
expect(requestData.site).to.be.an('object');
expect(requestData.site.id).to.equal(bidRequest.params.publisherId);
expect(requestData.site.domain).to.not.be.empty;
- expect(requestData.site.page).to.equal(bidderRequest.refererInfo.referer);
+ expect(requestData.site.page).to.equal(bidderRequest.refererInfo.page);
expect(requestData.at).to.equal(1);
expect(requestData.bcat).to.be.an('array').that.is.empty;
expect(requestData.cur).to.be.an('array').that.not.be.empty;
diff --git a/test/spec/modules/optimonAnalyticsAdapter_spec.js b/test/spec/modules/optimonAnalyticsAdapter_spec.js
index c50bfcb170f..406e9cb75c4 100644
--- a/test/spec/modules/optimonAnalyticsAdapter_spec.js
+++ b/test/spec/modules/optimonAnalyticsAdapter_spec.js
@@ -35,6 +35,7 @@ describe('Optimon Analytics Adapter', () => {
events.emit(constants.EVENTS.BID_TIMEOUT, optmn_arguments)
events.emit(constants.EVENTS.BID_WON, optmn_arguments)
- expect(optmn_queue.length).to.eql(3);
+ // 3 Optimon events + 1 Clean.io event
+ expect(optmn_queue.length).to.eql(4);
});
});
diff --git a/test/spec/modules/optoutBidAdapter_spec.js b/test/spec/modules/optoutBidAdapter_spec.js
index 4d7c25d12bc..a31becdc394 100644
--- a/test/spec/modules/optoutBidAdapter_spec.js
+++ b/test/spec/modules/optoutBidAdapter_spec.js
@@ -72,21 +72,21 @@ describe('optoutAdapterTest', function () {
}];
it('bidRequest HTTP method', function () {
- const requests = spec.buildRequests(bidRequests);
+ const requests = spec.buildRequests(bidRequests, {});
requests.forEach(function(requestItem) {
expect(requestItem.method).to.equal('POST');
});
});
it('bidRequest url without consent', function () {
- const requests = spec.buildRequests(bidRequests);
+ const requests = spec.buildRequests(bidRequests, {});
requests.forEach(function(requestItem) {
expect(requestItem.url).to.match(new RegExp('adscience-nocookie\\.nl/prebid/display'));
});
});
it('bidRequest id', function () {
- const requests = spec.buildRequests(bidRequests);
+ const requests = spec.buildRequests(bidRequests, {});
expect(requests[0].data.requestId).to.equal('9304jr394ddfj');
expect(requests[1].data.requestId).to.equal('893j4f94e8jei');
});
@@ -99,7 +99,7 @@ describe('optoutAdapterTest', function () {
}
})
- const requests = spec.buildRequests(bidRequests);
+ const requests = spec.buildRequests(bidRequests, {});
expect(requests[0].data.cur.adServerCurrency).to.equal('USD');
expect(requests[1].data.cur.adServerCurrency).to.equal('USD');
});
@@ -107,7 +107,7 @@ describe('optoutAdapterTest', function () {
it('bidRequest without config for currency', function () {
config.resetConfig();
- const requests = spec.buildRequests(bidRequests);
+ const requests = spec.buildRequests(bidRequests, {});
expect(requests[0].data.cur.adServerCurrency).to.equal('EUR');
expect(requests[1].data.cur.adServerCurrency).to.equal('EUR');
});
diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js
index 750524cf47f..0d1396866e7 100644
--- a/test/spec/modules/orbidderBidAdapter_spec.js
+++ b/test/spec/modules/orbidderBidAdapter_spec.js
@@ -63,7 +63,7 @@ describe('orbidderBidAdapter', () => {
return spec.buildRequests(buildRequest, {
...bidderRequest || {},
refererInfo: {
- referer: 'https://localhost:9876/'
+ page: 'https://localhost:9876/'
}
})[0];
};
diff --git a/test/spec/modules/otmBidAdapter_spec.js b/test/spec/modules/otmBidAdapter_spec.js
index ce033d0fba5..27da17b8415 100644
--- a/test/spec/modules/otmBidAdapter_spec.js
+++ b/test/spec/modules/otmBidAdapter_spec.js
@@ -42,7 +42,7 @@ describe('otmBidAdapter', function () {
sizes: [[240, 400]]
}];
- const bidderRequest = {refererInfo: {referer: `https://github.com:3000/`}}
+ const bidderRequest = {refererInfo: {page: `https://github.com:3000/`, domain: 'github.com:3000'}}
const request = spec.buildRequests(bidRequestData, bidderRequest);
const req_data = request[0].data;
diff --git a/test/spec/modules/outbrainBidAdapter_spec.js b/test/spec/modules/outbrainBidAdapter_spec.js
index 5dbdd049d82..5d7bebc1de1 100644
--- a/test/spec/modules/outbrainBidAdapter_spec.js
+++ b/test/spec/modules/outbrainBidAdapter_spec.js
@@ -180,7 +180,7 @@ describe('Outbrain Adapter', function () {
const commonBidderRequest = {
refererInfo: {
- referer: 'https://example.com/'
+ page: 'https://example.com/'
}
}
@@ -318,6 +318,27 @@ describe('Outbrain Adapter', function () {
expect(resData.badv).to.deep.equal(['bad-advertiser'])
});
+ it('first party data', function () {
+ const bidRequest = {
+ ...commonBidRequest,
+ ...nativeBidRequestParams,
+ }
+ const bidderRequest = {
+ ortb2: {
+ bcat: ['IAB1', 'IAB2-1'],
+ badv: ['domain1.com', 'domain2.com'],
+ wlang: ['en'],
+ },
+ ...commonBidderRequest,
+ }
+
+ const res = spec.buildRequests([bidRequest], bidderRequest)
+ const resData = JSON.parse(res.data)
+ expect(resData.bcat).to.deep.equal(bidderRequest.ortb2.bcat)
+ expect(resData.badv).to.deep.equal(bidderRequest.ortb2.badv)
+ expect(resData.wlang).to.deep.equal(bidderRequest.ortb2.wlang)
+ });
+
it('should pass bidder timeout', function () {
const bidRequest = {
...commonBidRequest,
diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js
index 658af310ea5..4c7e330b237 100644
--- a/test/spec/modules/ozoneBidAdapter_spec.js
+++ b/test/spec/modules/ozoneBidAdapter_spec.js
@@ -7,12 +7,6 @@ import * as utils from '../../../src/utils.js';
const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction';
const BIDDER_CODE = 'ozone';
-/*
-
-NOTE - use firefox console to deep copy the objects to use here
-
- */
-var originalPropertyBag = {'pageId': null};
var validBidRequests = [
{
adUnitCode: 'div-gpt-ad-1460505748561-0',
@@ -147,7 +141,6 @@ var validBidRequestsWithUserIdData = [
}]
}
]
-
}
];
var validBidRequestsMinimal = [
@@ -176,7 +169,6 @@ var validBidRequestsNoSizes = [
transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
}
];
-
var validBidRequestsWithBannerMediaType = [
{
adUnitCode: 'div-gpt-ad-1460505748561-0',
@@ -205,7 +197,6 @@ var validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo = [
transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
}
];
-
var validBidRequests1OutstreamVideo2020 = [
{
'bidder': 'ozone',
@@ -288,7 +279,6 @@ var validBidRequests1OutstreamVideo2020 = [
'bidderWinsCount': 0
}
];
-
var validBidderRequest1OutstreamVideo2020 = {
bidderRequest: {
auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
@@ -392,84 +382,79 @@ var validBidderRequest1OutstreamVideo2020 = {
}
};
var validBidderRequest = {
- bidderRequest: {
+ auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
+ auctionStart: 1536838908986,
+ bidderCode: 'ozone',
+ bidderRequestId: '1c1586b27a1b5c8',
+ bids: [{
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- auctionStart: 1536838908986,
- bidderCode: 'ozone',
+ bidId: '2899ec066a91ff8',
+ bidRequestsCount: 1,
+ bidder: 'ozone',
bidderRequestId: '1c1586b27a1b5c8',
- bids: [{
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'ozone',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }],
- doneCbCallCount: 1,
- start: 1536838908987,
- timeout: 3000
- }
+ crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
+ params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] },
+ sizes: [[300, 250], [300, 600]],
+ transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
+ }],
+ doneCbCallCount: 1,
+ start: 1536838908987,
+ timeout: 3000
};
-
var bidderRequestWithFullGdpr = {
- bidderRequest: {
+ auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
+ auctionStart: 1536838908986,
+ bidderCode: 'ozone',
+ bidderRequestId: '1c1586b27a1b5c8',
+ bids: [{
+ adUnitCode: 'div-gpt-ad-1460505748561-0',
auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- auctionStart: 1536838908986,
- bidderCode: 'ozone',
+ bidId: '2899ec066a91ff8',
+ bidRequestsCount: 1,
+ bidder: 'ozone',
bidderRequestId: '1c1586b27a1b5c8',
- bids: [{
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
- bidId: '2899ec066a91ff8',
- bidRequestsCount: 1,
- bidder: 'ozone',
- bidderRequestId: '1c1586b27a1b5c8',
- crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
- params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] },
- sizes: [[300, 250], [300, 600]],
- transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
- }],
- doneCbCallCount: 1,
- start: 1536838908987,
- timeout: 3000,
- gdprConsent: {
- 'consentString': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA',
- 'vendorData': {
- 'metadata': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA',
- 'gdprApplies': true,
- 'hasGlobalScope': false,
- 'cookieVersion': '1',
- 'created': '2019-05-31T12:46:48.825',
- 'lastUpdated': '2019-05-31T12:46:48.825',
- 'cmpId': '28',
- 'cmpVersion': '1',
- 'consentLanguage': 'en',
- 'consentScreen': '1',
- 'vendorListVersion': 148,
- 'maxVendorId': 631,
- 'purposeConsents': {
- '1': true,
- '2': true,
- '3': true,
- '4': true,
- '5': true
- },
- 'vendorConsents': {
- '468': true,
- '522': true,
- '524': true, /* 524 is ozone */
- '565': true,
- '591': true
- }
+ crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'},
+ params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] },
+ sizes: [[300, 250], [300, 600]],
+ transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87'
+ }],
+ doneCbCallCount: 1,
+ start: 1536838908987,
+ timeout: 3000,
+ gdprConsent: {
+ 'consentString': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA',
+ 'vendorData': {
+ 'metadata': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA',
+ 'gdprApplies': true,
+ 'hasGlobalScope': false,
+ 'cookieVersion': '1',
+ 'created': '2019-05-31T12:46:48.825',
+ 'lastUpdated': '2019-05-31T12:46:48.825',
+ 'cmpId': '28',
+ 'cmpVersion': '1',
+ 'consentLanguage': 'en',
+ 'consentScreen': '1',
+ 'vendorListVersion': 148,
+ 'maxVendorId': 631,
+ 'purposeConsents': {
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true
},
- 'gdprApplies': true
- }, }
+ 'vendorConsents': {
+ '468': true,
+ '522': true,
+ '524': true, /* 524 is ozone */
+ '565': true,
+ '591': true
+ }
+ },
+ 'gdprApplies': true
+ }
};
-
var gdpr1 = {
'consentString': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA',
'vendorData': {
@@ -502,7 +487,6 @@ var gdpr1 = {
},
'gdprApplies': true
};
-
var bidderRequestWithPartialGdpr = {
bidderRequest: {
auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99',
@@ -547,7 +531,6 @@ var bidderRequestWithPartialGdpr = {
}
}
};
-
var validResponse = {
'body': {
'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba',
@@ -604,7 +587,6 @@ var validResponse = {
},
'headers': {}
};
-
var validResponse2Bids = {
'body': {
'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba',
@@ -691,9 +673,6 @@ var validResponse2Bids = {
},
'headers': {}
};
-/*
-A bidder returns a bid for both sizes in an adunit
- */
var validResponse2BidsSameAdunit = {
'body': {
'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba',
@@ -780,14 +759,6 @@ var validResponse2BidsSameAdunit = {
},
'headers': {}
};
-/*
-
-SPECIAL CONSIDERATION FOR VIDEO TESTS:
-
-DO NOT USE _validVideoResponse directly - the interpretResponse function will modify it (adding a renderer!!!) so all
-subsequent calls will already have a renderer attached!!!
-
-*/
function getCleanValidVideoResponse() {
return JSON.parse(JSON.stringify(_validVideoResponse));
}
@@ -873,7 +844,6 @@ var _validVideoResponse = {
},
'headers': {}
};
-
var validBidResponse1adWith2Bidders = {
'body': {
'id': '91221f96-b931-4acc-8f05-c2a1186fa5ac',
@@ -964,11 +934,6 @@ var validBidResponse1adWith2Bidders = {
},
'headers': {}
};
-
-/*
-testing 2 ads, 2 bidders, one bidder bids for both slots in one adunit
- */
-
var multiRequest1 = [
{
'bidder': 'ozone',
@@ -1101,182 +1066,178 @@ var multiRequest1 = [
'bidderWinsCount': 0
}
];
-
var multiBidderRequest1 = {
- bidderRequest: {
- 'bidderCode': 'ozone',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'bids': [
- {
- 'bidder': 'ozone',
- 'params': {
- 'publisherId': 'OZONERUP0001',
- 'siteId': '4204204201',
- 'placementId': '0420420421',
- 'customData': [
- {
- 'settings': {},
- 'targeting': {
- 'sens': 'f',
- 'pt1': '/uk',
- 'pt2': 'uk',
- 'pt3': 'network-front',
- 'pt4': 'ng',
- 'pt5': [
- 'uk'
- ],
- 'pt7': 'desktop',
- 'pt8': [
- 'tfmqxwj7q',
- 'txeh7uyo0',
- 't8nxz6qzd',
- 't8nyiude5',
- 'sek9ghqwi'
- ],
- 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
- }
- }
- ]
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [
- [
- 300,
- 250
+ 'bidderCode': 'ozone',
+ 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
+ 'bidderRequestId': '1d03a1dfc563fc',
+ 'bids': [
+ {
+ 'bidder': 'ozone',
+ 'params': {
+ 'publisherId': 'OZONERUP0001',
+ 'siteId': '4204204201',
+ 'placementId': '0420420421',
+ 'customData': [
+ {
+ 'settings': {},
+ 'targeting': {
+ 'sens': 'f',
+ 'pt1': '/uk',
+ 'pt2': 'uk',
+ 'pt3': 'network-front',
+ 'pt4': 'ng',
+ 'pt5': [
+ 'uk'
],
- [
- 300,
- 600
- ]
- ]
+ 'pt7': 'desktop',
+ 'pt8': [
+ 'tfmqxwj7q',
+ 'txeh7uyo0',
+ 't8nxz6qzd',
+ 't8nyiude5',
+ 'sek9ghqwi'
+ ],
+ 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
+ }
}
- },
- 'adUnitCode': 'mpu',
- 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651',
- 'sizes': [
- [
- 300,
- 250
- ],
- [
- 300,
- 600
- ]
- ],
- 'bidId': '2d30e86db743a8',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
+ ]
},
- {
- 'bidder': 'ozone',
- 'params': {
- 'publisherId': 'OZONERUP0001',
- 'siteId': '4204204201',
- 'placementId': '0420420421',
- 'customData': [
- {
- 'settings': {},
- 'targeting': {
- 'sens': 'f',
- 'pt1': '/uk',
- 'pt2': 'uk',
- 'pt3': 'network-front',
- 'pt4': 'ng',
- 'pt5': [
- 'uk'
- ],
- 'pt7': 'desktop',
- 'pt8': [
- 'tfmqxwj7q',
- 'penl4dfdk',
- 't8nxz6qzd',
- 't8nyiude5',
- 'sek9ghqwi'
- ],
- 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
- }
- }
- ]
- },
- 'mediaTypes': {
- 'banner': {
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 250
- ]
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [
+ [
+ 300,
+ 250
+ ],
+ [
+ 300,
+ 600
]
- }
- },
- 'adUnitCode': 'leaderboard',
- 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0',
- 'sizes': [
- [
- 728,
- 90
- ],
- [
- 970,
- 250
]
+ }
+ },
+ 'adUnitCode': 'mpu',
+ 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651',
+ 'sizes': [
+ [
+ 300,
+ 250
],
- 'bidId': '3025f169863b7f8',
- 'bidderRequestId': '1d03a1dfc563fc',
- 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
- 'src': 'client',
- 'bidRequestsCount': 1,
- 'bidderRequestsCount': 1,
- 'bidderWinsCount': 0
- }
- ],
- 'auctionStart': 1592918645574,
- 'timeout': 3000,
- 'refererInfo': {
- 'referer': 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true',
- 'reachedTop': true,
- 'numIframes': 0,
- 'stack': [
- 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true'
- ]
+ [
+ 300,
+ 600
+ ]
+ ],
+ 'bidId': '2d30e86db743a8',
+ 'bidderRequestId': '1d03a1dfc563fc',
+ 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
},
- 'gdprConsent': {
- 'consentString': 'BOvy5sFO1dBa2AKAiBENDP-AAAAwVrv7_77-_9f-_f__9uj3Gr_v_f__32ccL5tv3h_7v-_7fi_-0nV4u_1tft9ydk1-5ctDztp507iakiPHmqNeb9n_mz1eZpRP58E09j53z7Ew_v8_v-b7BCPN_Y3v-8K96kA',
- 'vendorData': {
- 'metadata': 'BOvy5sFO1dBa2AKAiBENDPA',
- 'gdprApplies': true,
- 'hasGlobalConsent': false,
- 'hasGlobalScope': false,
- 'purposeConsents': {
- '1': true,
- '2': true,
- '3': true,
- '4': true,
- '5': true
- },
- 'vendorConsents': {
- '1': true,
- '2': true,
- '3': false,
- '4': true,
- '5': true
+ {
+ 'bidder': 'ozone',
+ 'params': {
+ 'publisherId': 'OZONERUP0001',
+ 'siteId': '4204204201',
+ 'placementId': '0420420421',
+ 'customData': [
+ {
+ 'settings': {},
+ 'targeting': {
+ 'sens': 'f',
+ 'pt1': '/uk',
+ 'pt2': 'uk',
+ 'pt3': 'network-front',
+ 'pt4': 'ng',
+ 'pt5': [
+ 'uk'
+ ],
+ 'pt7': 'desktop',
+ 'pt8': [
+ 'tfmqxwj7q',
+ 'penl4dfdk',
+ 't8nxz6qzd',
+ 't8nyiude5',
+ 'sek9ghqwi'
+ ],
+ 'pt9': '|k0xw2vqzp33kklb3j5w4|||'
+ }
+ }
+ ]
+ },
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [
+ [
+ 728,
+ 90
+ ],
+ [
+ 970,
+ 250
+ ]
+ ]
}
},
- 'gdprApplies': true
+ 'adUnitCode': 'leaderboard',
+ 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0',
+ 'sizes': [
+ [
+ 728,
+ 90
+ ],
+ [
+ 970,
+ 250
+ ]
+ ],
+ 'bidId': '3025f169863b7f8',
+ 'bidderRequestId': '1d03a1dfc563fc',
+ 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ }
+ ],
+ 'auctionStart': 1592918645574,
+ 'timeout': 3000,
+ 'refererInfo': {
+ 'referer': 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true',
+ 'reachedTop': true,
+ 'numIframes': 0,
+ 'stack': [
+ 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true'
+ ]
+ },
+ 'gdprConsent': {
+ 'consentString': 'BOvy5sFO1dBa2AKAiBENDP-AAAAwVrv7_77-_9f-_f__9uj3Gr_v_f__32ccL5tv3h_7v-_7fi_-0nV4u_1tft9ydk1-5ctDztp507iakiPHmqNeb9n_mz1eZpRP58E09j53z7Ew_v8_v-b7BCPN_Y3v-8K96kA',
+ 'vendorData': {
+ 'metadata': 'BOvy5sFO1dBa2AKAiBENDPA',
+ 'gdprApplies': true,
+ 'hasGlobalConsent': false,
+ 'hasGlobalScope': false,
+ 'purposeConsents': {
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true
+ },
+ 'vendorConsents': {
+ '1': true,
+ '2': true,
+ '3': false,
+ '4': true,
+ '5': true
+ }
},
- 'start': 1592918645578
- }
+ 'gdprApplies': true
+ },
+ 'start': 1592918645578
};
-
var multiResponse1 = {
'body': {
'id': '592ee33b-fb2e-4c00-b2d5-383e99cac57f',
@@ -1488,11 +1449,6 @@ var multiResponse1 = {
},
'headers': {}
};
-
-/*
---------------------end of 2 slots, 2 ----------------------------
- */
-
describe('ozone Adapter', function () {
describe('isBidRequestValid', function () {
let validBidReq = {
@@ -1503,13 +1459,10 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should return true when required params found', function () {
expect(spec.isBidRequestValid(validBidReq)).to.equal(true);
});
-
var validBidReq2 = {
-
bidder: BIDDER_CODE,
params: {
placementId: '1310000099',
@@ -1519,11 +1472,9 @@ describe('ozone Adapter', function () {
},
siteId: 1234567890
}
-
it('should return true when required params found and all optional params are valid', function () {
expect(spec.isBidRequestValid(validBidReq2)).to.equal(true);
});
-
var xEmptyPlacement = {
bidder: BIDDER_CODE,
params: {
@@ -1532,11 +1483,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate empty placementId', function () {
expect(spec.isBidRequestValid(xEmptyPlacement)).to.equal(false);
});
-
var xMissingPlacement = {
bidder: BIDDER_CODE,
params: {
@@ -1544,11 +1493,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate missing placementId', function () {
expect(spec.isBidRequestValid(xMissingPlacement)).to.equal(false);
});
-
var xBadPlacement = {
bidder: BIDDER_CODE,
params: {
@@ -1557,11 +1504,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate placementId with a non-numeric value', function () {
expect(spec.isBidRequestValid(xBadPlacement)).to.equal(false);
});
-
var xBadPlacementTooShort = {
bidder: BIDDER_CODE,
params: {
@@ -1570,11 +1515,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate placementId with a numeric value of wrong length', function () {
expect(spec.isBidRequestValid(xBadPlacementTooShort)).to.equal(false);
});
-
var xBadPlacementTooLong = {
bidder: BIDDER_CODE,
params: {
@@ -1583,11 +1526,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate placementId with a numeric value of wrong length', function () {
expect(spec.isBidRequestValid(xBadPlacementTooLong)).to.equal(false);
});
-
var xMissingPublisher = {
bidder: BIDDER_CODE,
params: {
@@ -1595,11 +1536,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate missing publisherId', function () {
expect(spec.isBidRequestValid(xMissingPublisher)).to.equal(false);
});
-
var xMissingSiteId = {
bidder: BIDDER_CODE,
params: {
@@ -1607,11 +1546,9 @@ describe('ozone Adapter', function () {
placementId: '1234567890',
}
};
-
it('should not validate missing sitetId', function () {
expect(spec.isBidRequestValid(xMissingSiteId)).to.equal(false);
});
-
var xBadPublisherTooShort = {
bidder: BIDDER_CODE,
params: {
@@ -1620,11 +1557,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate publisherId being too short', function () {
expect(spec.isBidRequestValid(xBadPublisherTooShort)).to.equal(false);
});
-
var xBadPublisherTooLong = {
bidder: BIDDER_CODE,
params: {
@@ -1633,11 +1568,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate publisherId being too long', function () {
expect(spec.isBidRequestValid(xBadPublisherTooLong)).to.equal(false);
});
-
var publisherNumericOk = {
bidder: BIDDER_CODE,
params: {
@@ -1646,11 +1579,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should validate publisherId being 12 digits', function () {
expect(spec.isBidRequestValid(publisherNumericOk)).to.equal(true);
});
-
var xEmptyPublisher = {
bidder: BIDDER_CODE,
params: {
@@ -1659,11 +1590,9 @@ describe('ozone Adapter', function () {
siteId: '1234567890'
}
};
-
it('should not validate empty publisherId', function () {
expect(spec.isBidRequestValid(xEmptyPublisher)).to.equal(false);
});
-
var xBadSite = {
bidder: BIDDER_CODE,
params: {
@@ -1672,37 +1601,15 @@ describe('ozone Adapter', function () {
siteId: '12345Z'
}
};
-
it('should not validate bad siteId', function () {
expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
});
-
- var xBadSiteTooLong = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- publisherId: '9876abcd12-3',
- siteId: '12345678901'
- }
- };
-
it('should not validate siteId too long', function () {
expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
});
-
- var xBadSiteTooShort = {
- bidder: BIDDER_CODE,
- params: {
- placementId: '1234567890',
- publisherId: '9876abcd12-3',
- siteId: '123456789'
- }
- };
-
it('should not validate siteId too short', function () {
expect(spec.isBidRequestValid(xBadSite)).to.equal(false);
});
-
var allNonStrings = {
bidder: BIDDER_CODE,
params: {
@@ -1711,11 +1618,9 @@ describe('ozone Adapter', function () {
siteId: 1234567890
}
};
-
it('should validate all numeric values being sent as non-string numbers', function () {
expect(spec.isBidRequestValid(allNonStrings)).to.equal(true);
});
-
var emptySiteId = {
bidder: BIDDER_CODE,
params: {
@@ -1724,11 +1629,9 @@ describe('ozone Adapter', function () {
siteId: ''
}
};
-
it('should not validate siteId being empty string (it is required now)', function () {
expect(spec.isBidRequestValid(emptySiteId)).to.equal(false);
});
-
var xBadCustomData = {
bidder: BIDDER_CODE,
params: {
@@ -1738,12 +1641,10 @@ describe('ozone Adapter', function () {
'customData': 'this aint gonna work'
}
};
-
it('should not validate customData not being an array', function () {
expect(spec.isBidRequestValid(xBadCustomData)).to.equal(false);
});
-
- var xBadCustomData_OLD_CUSTOMDATA_VALUE = {
+ var xBadCustomDataOldCustomdataValue = {
bidder: BIDDER_CODE,
params: {
'placementId': '1234567890',
@@ -1752,12 +1653,10 @@ describe('ozone Adapter', function () {
'customData': {'gender': 'bart', 'age': 'low'}
}
};
-
it('should not validate customData being an object, not an array', function () {
- expect(spec.isBidRequestValid(xBadCustomData_OLD_CUSTOMDATA_VALUE)).to.equal(false);
+ expect(spec.isBidRequestValid(xBadCustomDataOldCustomdataValue)).to.equal(false);
});
-
- var xBadCustomData_zerocd = {
+ var xBadCustomDataZerocd = {
bidder: BIDDER_CODE,
params: {
'placementId': '1111111110',
@@ -1766,12 +1665,10 @@ describe('ozone Adapter', function () {
'customData': []
}
};
-
it('should not validate customData array having no elements', function () {
- expect(spec.isBidRequestValid(xBadCustomData_zerocd)).to.equal(false);
+ expect(spec.isBidRequestValid(xBadCustomDataZerocd)).to.equal(false);
});
-
- var xBadCustomData_notargeting = {
+ var xBadCustomDataNotargeting = {
bidder: BIDDER_CODE,
params: {
'placementId': '1234567890',
@@ -1781,10 +1678,9 @@ describe('ozone Adapter', function () {
}
};
it('should not validate customData[] having no "targeting"', function () {
- expect(spec.isBidRequestValid(xBadCustomData_notargeting)).to.equal(false);
+ expect(spec.isBidRequestValid(xBadCustomDataNotargeting)).to.equal(false);
});
-
- var xBadCustomData_tgt_not_obj = {
+ var xBadCustomDataTgtNotObj = {
bidder: BIDDER_CODE,
params: {
'placementId': '1234567890',
@@ -1794,9 +1690,8 @@ describe('ozone Adapter', function () {
}
};
it('should not validate customData[0].targeting not being an object', function () {
- expect(spec.isBidRequestValid(xBadCustomData_tgt_not_obj)).to.equal(false);
+ expect(spec.isBidRequestValid(xBadCustomDataTgtNotObj)).to.equal(false);
});
-
var xBadCustomParams = {
bidder: BIDDER_CODE,
params: {
@@ -1821,11 +1716,9 @@ describe('ozone Adapter', function () {
mimes: ['video/mp4']}
}
};
-
it('should not validate video without context attribute', function () {
expect(spec.isBidRequestValid(xBadVideoContext2)).to.equal(false);
});
-
let validVideoBidReq = {
bidder: BIDDER_CODE,
params: {
@@ -1839,7 +1732,6 @@ describe('ozone Adapter', function () {
'context': 'outstream'},
}
};
-
it('should validate video outstream being sent', function () {
expect(spec.isBidRequestValid(validVideoBidReq)).to.equal(true);
});
@@ -1849,47 +1741,44 @@ describe('ozone Adapter', function () {
expect(spec.isBidRequestValid(instreamVid)).to.equal(true);
});
});
-
describe('buildRequests', function () {
+ beforeEach(function () {
+ config.resetConfig()
+ });
it('sends bid request to OZONEURI via POST', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
expect(request.url).to.equal(OZONEURI);
expect(request.method).to.equal('POST');
});
-
it('sends data as a string', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
expect(request.data).to.be.a('string');
});
-
it('sends all bid parameters', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
});
-
it('adds all parameters inside the ext object only', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
expect(request.data).to.be.a('string');
var data = JSON.parse(request.data);
expect(data.imp[0].ext.ozone.customData).to.be.an('array');
expect(request).not.to.have.key('lotameData');
expect(request).not.to.have.key('customData');
});
-
it('adds all parameters inside the ext object only - lightning', function () {
let localBidReq = JSON.parse(JSON.stringify(validBidRequests));
- const request = spec.buildRequests(localBidReq, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(localBidReq, validBidderRequest);
expect(request.data).to.be.a('string');
var data = JSON.parse(request.data);
expect(data.imp[0].ext.ozone.customData).to.be.an('array');
expect(request).not.to.have.key('lotameData');
expect(request).not.to.have.key('customData');
});
-
it('ignores ozoneData in & after version 2.1.1', function () {
let validBidRequestsWithOzoneData = JSON.parse(JSON.stringify(validBidRequests));
validBidRequestsWithOzoneData[0].params.ozoneData = {'networkID': '3048', 'dfpSiteID': 'd.thesun', 'sectionID': 'homepage', 'path': '/', 'sec_id': 'null', 'sec': 'sec', 'topics': 'null', 'kw': 'null', 'aid': 'null', 'search': 'null', 'article_type': 'null', 'hide_ads': '', 'article_slug': 'null'};
- const request = spec.buildRequests(validBidRequestsWithOzoneData, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsWithOzoneData, validBidderRequest);
expect(request.data).to.be.a('string');
var data = JSON.parse(request.data);
expect(data.imp[0].ext.ozone.customData).to.be.an('array');
@@ -1897,43 +1786,36 @@ describe('ozone Adapter', function () {
expect(request).not.to.have.key('lotameData');
expect(request).not.to.have.key('customData');
});
-
it('has correct bidder', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
expect(request.bidderRequest.bids[0].bidder).to.equal(BIDDER_CODE);
});
-
it('handles mediaTypes element correctly', function () {
- const request = spec.buildRequests(validBidRequestsWithBannerMediaType, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsWithBannerMediaType, validBidderRequest);
expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
});
-
it('handles no ozone or custom data', function () {
- const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest);
expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
});
-
it('handles video mediaType element correctly, with outstream video', function () {
- const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest);
expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
});
-
it('should not crash when there is no sizes element at all', function () {
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
});
-
it('should be able to handle non-single requests', function () {
config.setConfig({'ozone': {'singleRequest': false}});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
expect(request).to.be.a('array');
expect(request[0]).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']);
config.setConfig({'ozone': {'singleRequest': true}});
});
-
it('should add gdpr consent information to the request when ozone is true', function () {
let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA==';
- let bidderRequest = validBidderRequest.bidderRequest;
+ let bidderRequest = validBidderRequest;
bidderRequest.gdprConsent = {
consentString: consentString,
gdprApplies: true,
@@ -1944,16 +1826,14 @@ describe('ozone Adapter', function () {
purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true}
}
}
-
const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest);
const payload = JSON.parse(request.data);
expect(payload.regs.ext.gdpr).to.equal(1);
expect(payload.user.ext.consent).to.equal(consentString);
});
-
it('should add gdpr consent information to the request when vendorData is missing vendorConsents (Mirror)', function () {
let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA==';
- let bidderRequest = validBidderRequest.bidderRequest;
+ let bidderRequest = validBidderRequest;
bidderRequest.gdprConsent = {
consentString: consentString,
gdprApplies: true,
@@ -1962,16 +1842,14 @@ describe('ozone Adapter', function () {
gdprApplies: true
}
}
-
const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest);
const payload = JSON.parse(request.data);
expect(payload.regs.ext.gdpr).to.equal(1);
expect(payload.user.ext.consent).to.equal(consentString);
});
-
it('should set regs.ext.gdpr flag to 0 when gdprApplies is false', function () {
let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA==';
- let bidderRequest = validBidderRequest.bidderRequest;
+ let bidderRequest = validBidderRequest;
bidderRequest.gdprConsent = {
consentString: consentString,
gdprApplies: false,
@@ -1982,15 +1860,13 @@ describe('ozone Adapter', function () {
purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true}
}
};
-
const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest);
const payload = JSON.parse(request.data);
expect(payload.regs.ext.gdpr).to.equal(0);
});
-
it('should not have imp[N].ext.ozone.userId', function () {
let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA==';
- let bidderRequest = validBidderRequest.bidderRequest;
+ let bidderRequest = validBidderRequest;
bidderRequest.gdprConsent = {
consentString: consentString,
gdprApplies: false,
@@ -2001,7 +1877,6 @@ describe('ozone Adapter', function () {
purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true}
}
};
-
let bidRequests = validBidRequests;
bidRequests[0]['userId'] = {
'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}},
@@ -2019,7 +1894,6 @@ describe('ozone Adapter', function () {
expect(firstBid).to.not.have.property('userId');
delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests
});
-
it('should pick up the value of pubcid when built using the pubCommonId module (not userId)', function () {
let bidRequests = validBidRequests;
bidRequests[0]['userId'] = {
@@ -2031,23 +1905,13 @@ describe('ozone Adapter', function () {
'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'}
};
bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids'];
- const request = spec.buildRequests(bidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(bidRequests, validBidderRequest);
const payload = JSON.parse(request.data);
expect(payload.ext.ozone.pubcid).to.equal(bidRequests[0]['crumbs']['pubcid']);
delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests
});
-
it('should add a user.ext.eids object to contain user ID data in the new location (Nov 2019) Updated Aug 2020', function() {
- const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest.bidderRequest);
- /*
- 'pubcid': '12345678',
- 'tdid': '1111tdid',
- 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } },
- 'criteoId': '1111criteoId',
- 'idl_env': 'liverampId',
- 'parrableId': {'eid': '01.5678.parrableid'}
- */
-
+ const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest);
const payload = JSON.parse(request.data);
expect(payload.user).to.exist;
expect(payload.user.ext).to.exist;
@@ -2067,12 +1931,11 @@ describe('ozone Adapter', function () {
expect(payload.user.ext.eids[6]['source']).to.equal('parrableId');
expect(payload.user.ext.eids[6]['uids'][0]['id']['eid']).to.equal('01.5678.parrableid');
});
-
it('replaces the auction url for a config override', function () {
spec.propertyBag.whitelabel = null;
let fakeOrigin = 'http://sometestendpoint';
config.setConfig({'ozone': {'endpointOverride': {'origin': fakeOrigin}}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
expect(request.url).to.equal(fakeOrigin + '/openrtb2/auction');
expect(request.method).to.equal('POST');
const data = JSON.parse(request.data);
@@ -2080,12 +1943,11 @@ describe('ozone Adapter', function () {
config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}});
spec.propertyBag.whitelabel = null;
});
-
it('replaces the FULL auction url for a config override', function () {
spec.propertyBag.whitelabel = null;
let fakeurl = 'http://sometestendpoint/myfullurl';
config.setConfig({'ozone': {'endpointOverride': {'auctionUrl': fakeurl}}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
expect(request.url).to.equal(fakeurl);
expect(request.method).to.equal('POST');
const data = JSON.parse(request.data);
@@ -2093,7 +1955,6 @@ describe('ozone Adapter', function () {
config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}});
spec.propertyBag.whitelabel = null;
});
-
it('replaces the renderer url for a config override', function () {
spec.propertyBag.whitelabel = null;
let fakeUrl = 'http://renderer.com';
@@ -2107,9 +1968,8 @@ describe('ozone Adapter', function () {
spec.propertyBag.whitelabel = null;
});
it('should generate all the adservertargeting keys correctly named', function () {
- var specMock = utils.deepClone(spec);
config.setConfig({'ozone': {'kvpPrefix': 'xx'}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(result[0].adserverTargeting).to.have.own.property('xx_appnexus_crid');
expect(utils.deepAccess(result[0].adserverTargeting, 'xx_appnexus_crid')).to.equal('98493581');
@@ -2118,33 +1978,28 @@ describe('ozone Adapter', function () {
expect(utils.deepAccess(result[0].adserverTargeting, 'xx_size')).to.equal('300x600');
expect(utils.deepAccess(result[0].adserverTargeting, 'xx_pb_r')).to.equal('0.50');
expect(utils.deepAccess(result[0].adserverTargeting, 'xx_bid')).to.equal('true');
- config.resetConfig();
});
it('should create a meta object on each bid returned', function () {
- var specMock = utils.deepClone(spec);
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(result[0]).to.have.own.property('meta');
expect(result[0].meta.advertiserDomains[0]).to.equal('http://prebid.org');
- config.resetConfig();
});
-
it('replaces the kvp prefix ', function () {
spec.propertyBag.whitelabel = null;
config.setConfig({'ozone': {'kvpPrefix': 'test'}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.ext.ozone).to.haveOwnProperty('test_rw');
config.setConfig({'ozone': {'kvpPrefix': null}});
spec.propertyBag.whitelabel = null;
});
-
it('handles an alias ', function () {
spec.propertyBag.whitelabel = null;
config.setConfig({'lmc': {'kvpPrefix': 'test'}});
let br = JSON.parse(JSON.stringify(validBidRequests));
br[0]['bidder'] = 'lmc';
- const request = spec.buildRequests(br, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(br, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.ext.lmc).to.haveOwnProperty('test_rw');
config.setConfig({'lmc': {'kvpPrefix': null}}); // I cant remove the key so set the value to null
@@ -2155,7 +2010,7 @@ describe('ozone Adapter', function () {
specMock.getGetParametersAsObject = function() {
return {'oztestmode': 'mytestvalue_123'};
};
- const request = specMock.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = specMock.buildRequests(validBidRequests, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.imp[0].ext.ozone.customData).to.be.an('array');
expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123');
@@ -2165,7 +2020,7 @@ describe('ozone Adapter', function () {
specMock.getGetParametersAsObject = function() {
return {ozf: '1', ozpf: '0', ozrp: '2', ozip: '123'};
};
- const request = specMock.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = specMock.buildRequests(validBidRequests, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.ext.ozone.ozf).to.equal(1);
expect(data.ext.ozone.ozpf).to.equal(0);
@@ -2177,7 +2032,7 @@ describe('ozone Adapter', function () {
specMock.getGetParametersAsObject = function() {
return {ozf: 'false', ozpf: 'true', ozrp: 'xyz', ozip: 'hello'};
};
- const request = specMock.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = specMock.buildRequests(validBidRequests, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.ext.ozone.ozf).to.equal(0);
expect(data.ext.ozone.ozpf).to.equal(1);
@@ -2189,7 +2044,7 @@ describe('ozone Adapter', function () {
specMock.getGetParametersAsObject = function() {
return {'oztestmode': 'mytestvalue_123'};
};
- const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest);
+ const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.imp[0].ext.ozone.customData).to.be.an('array');
expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123');
@@ -2199,17 +2054,16 @@ describe('ozone Adapter', function () {
specMock.getGetParametersAsObject = function() {
return {};
};
- let request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest);
+ let request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
let url = request.url;
expect(url).to.equal('https://elb.the-ozone-project.com/openrtb2/auction');
let cookieUrl = specMock.getCookieSyncUrl();
expect(cookieUrl).to.equal('https://elb.the-ozone-project.com/static/load-cookie.html');
-
specMock = utils.deepClone(spec);
specMock.getGetParametersAsObject = function() {
return {'auction': 'dev', 'cookiesync': 'dev'};
};
- request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest);
+ request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
url = request.url;
expect(url).to.equal('https://test.ozpr.net/openrtb2/auction');
cookieUrl = specMock.getCookieSyncUrl();
@@ -2220,7 +2074,7 @@ describe('ozone Adapter', function () {
specMock.getGetParametersAsObject = function() {
return {'ozstoredrequest': '1122334455'}; // 10 digits are valid
};
- const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest);
+ const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.ext.ozone.oz_rw).to.equal(1);
expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1122334455');
@@ -2230,71 +2084,65 @@ describe('ozone Adapter', function () {
specMock.getGetParametersAsObject = function() {
return {'ozstoredrequest': 'BADVAL'}; // 10 digits are valid
};
- const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest);
+ const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.ext.ozone.oz_rw).to.equal(0);
expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1310000099');
});
-
it('should pick up the config value of coppa & set it in the request', function () {
config.setConfig({'coppa': true});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
const payload = JSON.parse(request.data);
expect(payload.regs).to.include.keys('coppa');
expect(payload.regs.coppa).to.equal(1);
- config.resetConfig();
});
it('should pick up the config value of coppa & only set it in the request if its true', function () {
config.setConfig({'coppa': false});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
const payload = JSON.parse(request.data);
expect(utils.deepAccess(payload, 'regs.coppa')).to.be.undefined;
- config.resetConfig();
});
it('should handle oz_omp_floor correctly', function () {
config.setConfig({'ozone': {'oz_omp_floor': 1.56}});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
const payload = JSON.parse(request.data);
expect(utils.deepAccess(payload, 'ext.ozone.oz_omp_floor')).to.equal(1.56);
- config.resetConfig();
});
it('should ignore invalid oz_omp_floor values', function () {
config.setConfig({'ozone': {'oz_omp_floor': '1.56'}});
- const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest);
const payload = JSON.parse(request.data);
expect(utils.deepAccess(payload, 'ext.ozone.oz_omp_floor')).to.be.undefined;
- config.resetConfig();
});
it('should should contain a unique page view id in the auction request which persists across calls', function () {
- let request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ let request = spec.buildRequests(validBidRequests, validBidderRequest);
let payload = JSON.parse(request.data);
expect(utils.deepAccess(payload, 'ext.ozone.pv')).to.be.a('string');
- request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest);
+ request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest);
let payload2 = JSON.parse(request.data);
expect(utils.deepAccess(payload2, 'ext.ozone.pv')).to.be.a('string');
expect(utils.deepAccess(payload2, 'ext.ozone.pv')).to.equal(utils.deepAccess(payload, 'ext.ozone.pv'));
});
it('should indicate that the whitelist was used when it contains valid data', function () {
config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_ozappnexus_pb', 'oz_ozappnexus_imp_id']}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const payload = JSON.parse(request.data);
expect(payload.ext.ozone.oz_kvp_rw).to.equal(1);
- config.resetConfig();
});
it('should indicate that the whitelist was not used when it contains no data', function () {
config.setConfig({'ozone': {'oz_whitelist_adserver_keys': []}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const payload = JSON.parse(request.data);
expect(payload.ext.ozone.oz_kvp_rw).to.equal(0);
- config.resetConfig();
});
it('should indicate that the whitelist was not used when it is not set in the config', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const payload = JSON.parse(request.data);
expect(payload.ext.ozone.oz_kvp_rw).to.equal(0);
});
it('should handle ortb2 site data', function () {
- config.setConfig({'ortb2': {
+ let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
+ bidderRequest.ortb2 = {
'site': {
'name': 'example_ortb2_name',
'domain': 'page.example.com',
@@ -2306,15 +2154,15 @@ describe('ozone Adapter', function () {
'keywords': 'power tools, drills',
'search': 'drill'
}
- }});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ };
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
const payload = JSON.parse(request.data);
expect(payload.imp[0].ext.ozone.customData[0].targeting.name).to.equal('example_ortb2_name');
expect(payload.user.ext).to.not.have.property('gender');
- config.resetConfig();
});
it('should add ortb2 site data when there is no customData already created', function () {
- config.setConfig({'ortb2': {
+ let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
+ bidderRequest.ortb2 = {
'site': {
'name': 'example_ortb2_name',
'domain': 'page.example.com',
@@ -2326,42 +2174,41 @@ describe('ozone Adapter', function () {
'keywords': 'power tools, drills',
'search': 'drill'
}
- }});
- const request = spec.buildRequests(validBidRequestsNoCustomData, validBidderRequest.bidderRequest);
+ };
+ const request = spec.buildRequests(validBidRequestsNoCustomData, bidderRequest);
const payload = JSON.parse(request.data);
expect(payload.imp[0].ext.ozone.customData[0].targeting.name).to.equal('example_ortb2_name');
expect(payload.imp[0].ext.ozone.customData[0].targeting).to.not.have.property('gender')
- config.resetConfig();
});
it('should add ortb2 user data to the user object', function () {
- config.setConfig({'ortb2': {
+ let bidderRequest = JSON.parse(JSON.stringify(validBidderRequest));
+ bidderRequest.ortb2 = {
'user': {
- 'gender': 'who knows these days'
+ 'gender': 'I identify as a box of rocks'
}
- }});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ };
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
const payload = JSON.parse(request.data);
- expect(payload.user.gender).to.equal('who knows these days');
- config.resetConfig();
+ expect(payload.user.gender).to.equal('I identify as a box of rocks');
});
it('should not override the user.ext.consent string even if this is set in config ortb2', function () {
- config.setConfig({'ortb2': {
+ let bidderRequest = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr));
+ bidderRequest.ortb2 = {
'user': {
'ext': {
'consent': 'this is the consent override that shouldnt work',
'consent2': 'this should be set'
}
}
- }});
- const request = spec.buildRequests(validBidRequests, bidderRequestWithFullGdpr.bidderRequest);
+ };
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
const payload = JSON.parse(request.data);
expect(payload.user.ext.consent2).to.equal('this should be set');
expect(payload.user.ext.consent).to.equal('BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA');
- config.resetConfig();
});
it('should have openrtb video params', function() {
let allowed = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype', 'ext'];
- const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest);
const payload = JSON.parse(request.data);
const vid = (payload.imp[0].video);
const keys = Object.keys(vid);
@@ -2391,13 +2238,11 @@ describe('ozone Adapter', function () {
});
let localBidRequest = JSON.parse(JSON.stringify(validBidRequestsWithBannerMediaType));
localBidRequest[0].getFloor = function(x) { return {'currency': 'USD', 'floor': 0.8} };
- const request = spec.buildRequests(localBidRequest, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(localBidRequest, validBidderRequest);
const payload = JSON.parse(request.data);
expect(utils.deepAccess(payload, 'imp.0.floor.banner.currency')).to.equal('USD');
expect(utils.deepAccess(payload, 'imp.0.floor.banner.floor')).to.equal(0.8);
- config.resetConfig();
});
-
it('handles schain object in each bidrequest (will be the same in each br)', function () {
let br = JSON.parse(JSON.stringify(validBidRequests));
let schainConfigObject = {
@@ -2412,44 +2257,44 @@ describe('ozone Adapter', function () {
]
};
br[0]['schain'] = schainConfigObject;
- const request = spec.buildRequests(br, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(br, validBidderRequest);
const data = JSON.parse(request.data);
expect(data.source.ext).to.haveOwnProperty('schain');
expect(data.source.ext.schain).to.deep.equal(schainConfigObject); // .deep.equal() : Target object deeply (but not strictly) equals `{a: 1}`
});
});
-
describe('interpretResponse', function () {
+ beforeEach(function () {
+ config.resetConfig()
+ })
it('should build bid array', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(result.length).to.equal(1);
});
-
it('should have all relevant fields', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
const bid = result[0];
expect(bid.cpm).to.equal(validResponse.body.seatbid[0].bid[0].cpm);
expect(bid.width).to.equal(validResponse.body.seatbid[0].bid[0].width);
expect(bid.height).to.equal(validResponse.body.seatbid[0].bid[0].height);
});
-
it('should build bid array with gdpr', function () {
- let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr.bidderRequest));
+ let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr));
validBR.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'};
const request = spec.buildRequests(validBidRequests, validBR); // works the old way, with GDPR not enforced by default
const result = spec.interpretResponse(validResponse, request);
expect(result.length).to.equal(1);
});
it('should build bid array with usp/CCPA', function () {
- let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr.bidderRequest));
+ let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr));
validBR.uspConsent = '1YNY';
const request = spec.buildRequests(validBidRequests, validBR);
const payload = JSON.parse(request.data);
- expect(payload.user.ext.uspConsent).to.equal('1YNY');
+ expect(payload.user.ext.uspConsent).not.to.exist;
+ expect(payload.regs.ext.us_privacy).to.equal('1YNY');
});
-
it('should build bid array with only partial gdpr', function () {
var validBidderRequestWithGdpr = bidderRequestWithPartialGdpr.bidderRequest;
validBidderRequestWithGdpr.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'};
@@ -2457,26 +2302,22 @@ describe('ozone Adapter', function () {
const payload = JSON.parse(request.data);
expect(payload.user.ext.consent).to.be.a('string');
});
-
it('should fail ok if no seatbid in server response', function () {
const result = spec.interpretResponse({}, {});
expect(result).to.be.an('array');
expect(result).to.be.empty;
});
-
it('should fail ok if seatbid is not an array', function () {
const result = spec.interpretResponse({'body': {'seatbid': 'nothing_here'}}, {});
expect(result).to.be.an('array');
expect(result).to.be.empty;
});
-
it('should have video renderer for outstream video', function () {
const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest1OutstreamVideo2020.bidderRequest);
const result = spec.interpretResponse(getCleanValidVideoResponse(), validBidderRequest1OutstreamVideo2020);
const bid = result[0];
expect(bid.renderer).to.be.an.instanceOf(Renderer);
});
-
it('should have NO video renderer for instream video', function () {
let instreamRequestsObj = JSON.parse(JSON.stringify(validBidRequests1OutstreamVideo2020));
instreamRequestsObj[0].mediaTypes.video.context = 'instream';
@@ -2487,99 +2328,87 @@ describe('ozone Adapter', function () {
const bid = result[0];
expect(bid.hasOwnProperty('renderer')).to.be.false;
});
-
it('should correctly parse response where there are more bidders than ad slots', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validBidResponse1adWith2Bidders, request);
expect(result.length).to.equal(2);
});
-
it('should have a ttl of 600', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(result[0].ttl).to.equal(300);
});
-
it('should handle oz_omp_floor_dollars correctly, inserting 1 as necessary', function () {
config.setConfig({'ozone': {'oz_omp_floor': 0.01}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('1');
- config.resetConfig();
});
it('should handle oz_omp_floor_dollars correctly, inserting 0 as necessary', function () {
config.setConfig({'ozone': {'oz_omp_floor': 2.50}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('0');
- config.resetConfig();
});
it('should handle missing oz_omp_floor_dollars correctly, inserting nothing', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.be.undefined;
});
it('should handle ext.bidder.ozone.floor correctly, setting flr & rid as necessary', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
let vres = JSON.parse(JSON.stringify(validResponse));
vres.body.seatbid[0].bid[0].ext.bidder.ozone = {floor: 1, ruleId: 'ZjbsYE1q'};
const result = spec.interpretResponse(vres, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(1);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal('ZjbsYE1q');
- config.resetConfig();
});
it('should handle ext.bidder.ozone.floor correctly, inserting 0 as necessary', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
let vres = JSON.parse(JSON.stringify(validResponse));
vres.body.seatbid[0].bid[0].ext.bidder.ozone = {floor: 0, ruleId: 'ZjbXXE1q'};
const result = spec.interpretResponse(vres, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(0);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal('ZjbXXE1q');
- config.resetConfig();
});
it('should handle ext.bidder.ozone.floor correctly, inserting nothing as necessary', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
let vres = JSON.parse(JSON.stringify(validResponse));
vres.body.seatbid[0].bid[0].ext.bidder.ozone = {};
const result = spec.interpretResponse(vres, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr', null)).to.equal(null);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid', null)).to.equal(null);
- config.resetConfig();
});
it('should handle ext.bidder.ozone.floor correctly, when bidder.ozone is not there', function () {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
let vres = JSON.parse(JSON.stringify(validResponse));
const result = spec.interpretResponse(vres, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr', null)).to.equal(null);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid', null)).to.equal(null);
- config.resetConfig();
});
it('should handle a valid whitelist, removing items not on the list & leaving others', function () {
config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_adId']}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined;
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adId')).to.equal('2899ec066a91ff8-0-oz-0');
- config.resetConfig();
});
it('should ignore a whitelist if enhancedAdserverTargeting is false', function () {
config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_imp_id'], 'enhancedAdserverTargeting': false}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined;
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_imp_id')).to.be.undefined;
- config.resetConfig();
});
it('should correctly handle enhancedAdserverTargeting being false', function () {
config.setConfig({'ozone': {'enhancedAdserverTargeting': false}});
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.interpretResponse(validResponse, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined;
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_imp_id')).to.be.undefined;
- config.resetConfig();
});
it('should add flr into ads request if floor exists in the auction response', function () {
- const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest);
let validres = JSON.parse(JSON.stringify(validResponse2Bids));
validres.body.seatbid[0].bid[0].ext.bidder.ozone = {'floor': 1};
const result = spec.interpretResponse(validres, request);
@@ -2587,7 +2416,7 @@ describe('ozone Adapter', function () {
expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_flr', '')).to.equal('');
});
it('should add rid into ads request if ruleId exists in the auction response', function () {
- const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest);
let validres = JSON.parse(JSON.stringify(validResponse2Bids));
validres.body.seatbid[0].bid[0].ext.bidder.ozone = {'ruleId': 123};
const result = spec.interpretResponse(validres, request);
@@ -2595,13 +2424,13 @@ describe('ozone Adapter', function () {
expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_rid', '')).to.equal('');
});
it('should add oz_ozappnexus_sid (cid value) for all appnexus bids', function () {
- const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest);
let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit));
const result = spec.interpretResponse(validres, request);
expect(utils.deepAccess(result[0].adserverTargeting, 'oz_ozappnexus_sid')).to.equal(result[0].cid);
});
it('should add unique adId values to each bid', function() {
- const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit));
const result = spec.interpretResponse(validres, request);
expect(result.length).to.equal(1);
@@ -2610,7 +2439,7 @@ describe('ozone Adapter', function () {
});
it('should correctly process an auction with 2 adunits & multiple bidders one of which bids for both adslots', function() {
let validres = JSON.parse(JSON.stringify(multiResponse1));
- let request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest);
+ let request = spec.buildRequests(multiRequest1, multiBidderRequest1);
let result = spec.interpretResponse(validres, request);
expect(result.length).to.equal(4); // one of the 5 bids will have been removed
expect(result[1]['price']).to.equal(0.521);
@@ -2620,15 +2449,28 @@ describe('ozone Adapter', function () {
validres = JSON.parse(JSON.stringify(multiResponse1));
validres.body.seatbid[0].bid[1].price = 1.1;
validres.body.seatbid[0].bid[1].cpm = 1.1;
- request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest);
+ request = spec.buildRequests(multiRequest1, multiBidderRequest1);
result = spec.interpretResponse(validres, request);
expect(result[1]['price']).to.equal(1.1);
expect(result[1]['impid']).to.equal('3025f169863b7f8');
expect(result[1]['id']).to.equal('18552976939844681');
expect(result[1]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-oz-1');
});
+ it('should add mediaType: banner for a banner ad', function () {
+ const request = spec.buildRequests(validBidRequests, validBidderRequest);
+ const result = spec.interpretResponse(validResponse, request);
+ expect(result[0].mediaType).to.equal('banner');
+ });
+ it('should add mediaType: video for a video ad', function () {
+ let instreamRequestsObj = JSON.parse(JSON.stringify(validBidRequests1OutstreamVideo2020));
+ instreamRequestsObj[0].mediaTypes.video.context = 'instream';
+ let instreamBidderReq = JSON.parse(JSON.stringify(validBidderRequest1OutstreamVideo2020));
+ instreamBidderReq.bidderRequest.bids[0].mediaTypes.video.context = 'instream';
+ const result = spec.interpretResponse(getCleanValidVideoResponse(), instreamBidderReq);
+ const bid = result[0];
+ expect(bid.mediaType).to.equal('video');
+ });
});
-
describe('userSyncs', function () {
it('should fail gracefully if no server response', function () {
const result = spec.getUserSyncs('bad', false, gdpr1);
@@ -2639,7 +2481,7 @@ describe('ozone Adapter', function () {
expect(result).to.be.empty;
});
it('should append the various values if they exist', function() {
- spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1);
expect(result).to.be.an('array');
expect(result[0].url).to.include('publisherId=9876abcd12-3');
@@ -2648,19 +2490,18 @@ describe('ozone Adapter', function () {
expect(result[0].url).to.include('gdpr_consent=BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA');
});
it('should append ccpa (usp data)', function() {
- spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1, '1YYN');
expect(result).to.be.an('array');
expect(result[0].url).to.include('usp_consent=1YYN');
});
it('should use "" if no usp is sent to cookieSync', function() {
- spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest);
+ spec.buildRequests(validBidRequests, validBidderRequest);
const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1);
expect(result).to.be.an('array');
expect(result[0].url).to.include('usp_consent=&');
});
});
-
describe('video object utils', function () {
it('should find width & height from video object', function () {
let obj = {'playerSize': [640, 480], 'mimes': ['video/mp4'], 'context': 'outstream'};
@@ -2715,7 +2556,7 @@ describe('ozone Adapter', function () {
expect(result).to.be.null;
});
it('should add oz_appnexus_dealid into ads request if dealid exists in the auction response', function () {
- const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest);
+ const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest);
let validres = JSON.parse(JSON.stringify(validResponse2Bids));
validres.body.seatbid[0].bid[0].dealid = '1234';
const result = spec.interpretResponse(validres, request);
@@ -2723,7 +2564,6 @@ describe('ozone Adapter', function () {
expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_dealid', '')).to.equal('');
});
});
-
describe('default size', function () {
it('should should return default sizes if no obj is sent', function () {
let obj = '';
@@ -2732,7 +2572,6 @@ describe('ozone Adapter', function () {
expect(result.defaultWidth).to.equal(300);
});
});
-
describe('getGranularityKeyName', function() {
it('should return a string granularity as-is', function() {
const result = getGranularityKeyName('', 'this is it', '');
@@ -2747,7 +2586,6 @@ describe('ozone Adapter', function () {
expect(result).to.equal('string buckets');
});
});
-
describe('getGranularityObject', function() {
it('should return an object as-is', function() {
const result = getGranularityObject('', {'name': 'mark'}, '', '');
@@ -2758,19 +2596,19 @@ describe('ozone Adapter', function () {
expect(result.name).to.equal('rupert');
});
});
-
describe('blockTheRequest', function() {
+ beforeEach(function () {
+ config.resetConfig()
+ })
it('should return true if oz_request is false', function() {
config.setConfig({'ozone': {'oz_request': false}});
- let result = spec.blockTheRequest(bidderRequestWithFullGdpr);
+ let result = spec.blockTheRequest();
expect(result).to.be.true;
- config.resetConfig();
});
it('should return false if oz_request is true', function() {
config.setConfig({'ozone': {'oz_request': true}});
- let result = spec.blockTheRequest(bidderRequestWithFullGdpr);
+ let result = spec.blockTheRequest();
expect(result).to.be.false;
- config.resetConfig();
});
});
describe('getPageId', function() {
@@ -2876,11 +2714,10 @@ describe('ozone Adapter', function () {
expect(response[1].bid.length).to.equal(2);
});
});
- /**
- * spec.getWhitelabelConfigItem test - get a config value for a whitelabelled bidder,
- * from a standard ozone.oz_xxxx_yyy string
- */
describe('getWhitelabelConfigItem', function() {
+ beforeEach(function () {
+ config.resetConfig()
+ })
it('should fetch the whitelabelled equivalent config value correctly', function () {
var specMock = utils.deepClone(spec);
config.setConfig({'ozone': {'oz_omp_floor': 'ozone-floor-value'}});
@@ -2896,7 +2733,26 @@ describe('ozone Adapter', function () {
let testKey2 = 'ozone.singleRequest';
let markbidder_config2 = specMock.getWhitelabelConfigItem(testKey2);
expect(markbidder_config2).to.equal('markbidder-singlerequest-value');
- config.resetConfig();
+ });
+ });
+ describe('setBidMediaTypeIfNotExist', function() {
+ it('should leave the bid object alone if it already contains mediaType', function() {
+ let thisBid = {mediaType: 'marktest'};
+ spec.setBidMediaTypeIfNotExist(thisBid, 'replacement');
+ expect(thisBid.mediaType).to.equal('marktest');
+ });
+ it('should change the bid object if it doesnt already contain mediaType', function() {
+ let thisBid = {someKey: 'someValue'};
+ spec.setBidMediaTypeIfNotExist(thisBid, 'replacement');
+ expect(thisBid.mediaType).to.equal('replacement');
+ });
+ });
+ describe('getLoggableBidObject', function() {
+ it('should return an object without a "renderer" element', function () {
+ let obj = {'renderer': {}, 'somevalue': '', 'h': 100};
+ let ret = spec.getLoggableBidObject(obj);
+ expect(ret).to.not.have.own.property('renderer');
+ expect(ret.h).to.equal(100);
});
});
});
diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js
index a6e6185bbb2..55287e0bfec 100644
--- a/test/spec/modules/parrableIdSystem_spec.js
+++ b/test/spec/modules/parrableIdSystem_spec.js
@@ -96,6 +96,12 @@ function decodeBase64UrlSafe(encBase64) {
}
describe('Parrable ID System', function() {
+ after(() => {
+ // reset ID system to avoid delayed callbacks in other tests
+ config.resetConfig();
+ init(config);
+ });
+
describe('parrableIdSystem.getId()', function() {
describe('response callback function', function() {
let logErrorStub;
@@ -128,7 +134,7 @@ describe('Parrable ID System', function() {
expect(data).to.deep.equal({
eid: P_COOKIE_EID,
trackers: P_CONFIG_MOCK.params.partners.split(','),
- url: getRefererInfo().referer,
+ url: getRefererInfo().page,
prebidVersion: '$prebid.version$',
isIframe: true
});
@@ -649,7 +655,6 @@ describe('Parrable ID System', function() {
writeParrableCookie({ eid: P_COOKIE_EID, ibaOptout: true });
init(config);
setSubmoduleRegistry([parrableIdSubmodule]);
- config.setConfig(getConfigMock());
});
afterEach(function() {
@@ -659,6 +664,7 @@ describe('Parrable ID System', function() {
});
it('when a stored Parrable ID exists it is added to bids', function(done) {
+ config.setConfig(getConfigMock());
requestBidsHook(function() {
adUnits.forEach(unit => {
unit.bids.forEach(bid => {
@@ -685,6 +691,7 @@ describe('Parrable ID System', function() {
it('supplies an optout reason when the EID is missing due to CCPA non-consent', function(done) {
// the ID system itself will not write a cookie with an EID when CCPA=true
writeParrableCookie({ ccpaOptout: true });
+ config.setConfig(getConfigMock());
requestBidsHook(function() {
adUnits.forEach(unit => {
diff --git a/test/spec/modules/permutiveRtdProvider_spec.js b/test/spec/modules/permutiveRtdProvider_spec.js
index 6b44ec2b065..9282ec3ac24 100644
--- a/test/spec/modules/permutiveRtdProvider_spec.js
+++ b/test/spec/modules/permutiveRtdProvider_spec.js
@@ -5,9 +5,11 @@ import {
initSegments,
isAcEnabled,
isPermutiveOnPage,
- setBidderRtb
+ setBidderRtb,
+ getModuleConfig,
+ PERMUTIVE_SUBMODULE_CONFIG_KEY,
} from 'modules/permutiveRtdProvider.js'
-import { deepAccess } from '../../../src/utils.js'
+import { deepAccess, deepSetValue, mergeDeep } from '../../../src/utils.js'
import { config } from 'src/config.js'
describe('permutiveRtdProvider', function () {
@@ -29,6 +31,154 @@ describe('permutiveRtdProvider', function () {
})
})
+ describe('getModuleConfig', function () {
+ beforeEach(function () {
+ // Reads data from the cache
+ permutiveSubmodule.init()
+ })
+
+ const liftToParams = (params) => ({ params })
+
+ const getDefaultConfig = () => ({
+ waitForIt: false,
+ params: {
+ maxSegs: 500,
+ acBidders: [],
+ overwrites: {},
+ },
+ })
+
+ const storeConfigInCacheAndInit = (data) => {
+ const dataToStore = { [PERMUTIVE_SUBMODULE_CONFIG_KEY]: data }
+ setLocalStorage(dataToStore)
+ // Reads data from the cache
+ permutiveSubmodule.init()
+
+ // Cleanup
+ return () => removeLocalStorage(dataToStore)
+ }
+
+ const setWindowPermutivePrebid = (getPermutiveRtdConfig) => {
+ // Read from Permutive
+ const backup = window.permutive
+
+ deepSetValue(window, 'permutive.addons.prebid', {
+ getPermutiveRtdConfig,
+ })
+
+ // Cleanup
+ return () => window.permutive = backup
+ }
+
+ it('should return default values', function () {
+ const config = getModuleConfig({})
+ expect(config).to.deep.equal(getDefaultConfig())
+ })
+
+ it('should override deeply on custom config', function () {
+ const defaultConfig = getDefaultConfig()
+
+ const customModuleConfig = { waitForIt: true, params: { acBidders: ['123'] } }
+ const config = getModuleConfig(customModuleConfig)
+
+ expect(config).to.deep.equal(mergeDeep(defaultConfig, customModuleConfig))
+ })
+
+ it('should override deeply on cached config', function () {
+ const defaultConfig = getDefaultConfig()
+
+ const cachedParamsConfig = { acBidders: ['123'] }
+ const cleanupCache = storeConfigInCacheAndInit(cachedParamsConfig)
+
+ const config = getModuleConfig({})
+
+ expect(config).to.deep.equal(mergeDeep(defaultConfig, liftToParams(cachedParamsConfig)))
+
+ // Cleanup
+ cleanupCache()
+ })
+
+ it('should override deeply on Permutive Rtd config', function () {
+ const defaultConfig = getDefaultConfig()
+
+ const permutiveRtdConfigParams = { acBidders: ['123'], overwrites: { '123': true } }
+ const cleanupPermutive = setWindowPermutivePrebid(function () {
+ return permutiveRtdConfigParams
+ })
+
+ const config = getModuleConfig({})
+
+ expect(config).to.deep.equal(mergeDeep(defaultConfig, liftToParams(permutiveRtdConfigParams)))
+
+ // Cleanup
+ cleanupPermutive()
+ })
+
+ it('should NOT use cached Permutive Rtd config if window.permutive is available', function () {
+ const defaultConfig = getDefaultConfig()
+
+ // As Permutive is available on the window object, this value won't be used.
+ const cachedParamsConfig = { acBidders: ['123'] }
+ const cleanupCache = storeConfigInCacheAndInit(cachedParamsConfig)
+
+ const permutiveRtdConfigParams = { acBidders: ['456'], overwrites: { '123': true } }
+ const cleanupPermutive = setWindowPermutivePrebid(function () {
+ return permutiveRtdConfigParams
+ })
+
+ const config = getModuleConfig({})
+
+ expect(config).to.deep.equal(mergeDeep(defaultConfig, liftToParams(permutiveRtdConfigParams)))
+
+ // Cleanup
+ cleanupCache()
+ cleanupPermutive()
+ })
+
+ it('should handle calling Permutive method throwing error', function () {
+ const defaultConfig = getDefaultConfig()
+
+ const cleanupPermutive = setWindowPermutivePrebid(function () {
+ throw new Error()
+ })
+
+ const config = getModuleConfig({})
+
+ expect(config).to.deep.equal(defaultConfig)
+
+ // Cleanup
+ cleanupPermutive()
+ })
+
+ it('should override deeply in priority order', function () {
+ const defaultConfig = getDefaultConfig()
+
+ // As Permutive is available on the window object, this value won't be used.
+ const cachedConfig = { acBidders: ['123'] }
+ const cleanupCache = storeConfigInCacheAndInit(cachedConfig)
+
+ // Read from Permutive
+ const permutiveRtdConfig = { acBidders: ['456'] }
+ const cleanupPermutive = setWindowPermutivePrebid(function () {
+ return permutiveRtdConfig
+ })
+
+ const customModuleConfig = { params: { acBidders: ['789'], maxSegs: 499 } }
+ const config = getModuleConfig(customModuleConfig)
+
+ // The configs are in reverse priority order as configs are merged left to right. So the priority is,
+ // 1. customModuleConfig <- set by publisher with pbjs.setConfig
+ // 2. permutiveRtdConfig <- set by the publisher using Permutive.
+ // 3. defaultConfig
+ const configMergedInPriorityOrder = mergeDeep(defaultConfig, liftToParams(permutiveRtdConfig), customModuleConfig)
+ expect(config).to.deep.equal(configMergedInPriorityOrder)
+
+ // Cleanup
+ cleanupCache()
+ cleanupPermutive()
+ })
+ })
+
describe('ortb2 config', function () {
beforeEach(function () {
config.resetConfig()
@@ -36,16 +186,16 @@ describe('permutiveRtdProvider', function () {
it('should add ortb2 config', function () {
const moduleConfig = getConfig()
- const bidderConfig = config.getBidderConfig()
+ const bidderConfig = {};
const acBidders = moduleConfig.params.acBidders
const expectedTargetingData = transformedTargeting().ac.map(seg => {
return { id: seg }
})
- setBidderRtb({}, moduleConfig)
+ setBidderRtb(bidderConfig, moduleConfig)
acBidders.forEach(bidder => {
- expect(bidderConfig[bidder].ortb2.user.data).to.deep.include.members([{
+ expect(bidderConfig[bidder].user.data).to.deep.include.members([{
name: 'permutive.com',
segment: expectedTargetingData
}])
@@ -53,7 +203,7 @@ describe('permutiveRtdProvider', function () {
})
it('should include ortb2 user data transformation for IAB audience taxonomy', function() {
const moduleConfig = getConfig()
- const bidderConfig = config.getBidderConfig()
+ const bidderConfig = {}
const acBidders = moduleConfig.params.acBidders
const expectedTargetingData = transformedTargeting().ac.map(seg => {
return { id: seg }
@@ -75,10 +225,10 @@ describe('permutiveRtdProvider', function () {
}
)
- setBidderRtb({}, moduleConfig)
+ setBidderRtb(bidderConfig, moduleConfig)
acBidders.forEach(bidder => {
- expect(bidderConfig[bidder].ortb2.user.data).to.deep.include.members([
+ expect(bidderConfig[bidder].user.data).to.deep.include.members([
{
name: 'permutive.com',
segment: expectedTargetingData
@@ -93,30 +243,24 @@ describe('permutiveRtdProvider', function () {
})
it('should not overwrite ortb2 config', function () {
const moduleConfig = getConfig()
- const bidderConfig = config.getBidderConfig()
const acBidders = moduleConfig.params.acBidders
const sampleOrtbConfig = {
- ortb2: {
- site: {
- name: 'example'
- },
- user: {
- keywords: 'a,b',
- data: [
- {
- name: 'www.dataprovider1.com',
- ext: { taxonomyname: 'iab_audience_taxonomy' },
- segment: [{ id: '687' }, { id: '123' }]
- }
- ]
- }
+ site: {
+ name: 'example'
+ },
+ user: {
+ keywords: 'a,b',
+ data: [
+ {
+ name: 'www.dataprovider1.com',
+ ext: { taxonomyname: 'iab_audience_taxonomy' },
+ segment: [{ id: '687' }, { id: '123' }]
+ }
+ ]
}
}
- config.setBidderConfig({
- bidders: acBidders,
- config: sampleOrtbConfig
- })
+ const bidderConfig = Object.fromEntries(acBidders.map(bidder => [bidder, sampleOrtbConfig]))
const transformedUserData = {
name: 'transformation',
@@ -124,14 +268,15 @@ describe('permutiveRtdProvider', function () {
segment: [1, 2, 3]
}
- setBidderRtb({}, moduleConfig, {
+ setBidderRtb(bidderConfig, moduleConfig, {
+ // TODO: this argument is unused, is the test still valid / needed?
testTransformation: userData => transformedUserData
})
acBidders.forEach(bidder => {
- expect(bidderConfig[bidder].ortb2.site.name).to.equal(sampleOrtbConfig.ortb2.site.name)
- expect(bidderConfig[bidder].ortb2.user.keywords).to.equal(sampleOrtbConfig.ortb2.user.keywords)
- expect(bidderConfig[bidder].ortb2.user.data).to.deep.include.members([sampleOrtbConfig.ortb2.user.data[0]])
+ expect(bidderConfig[bidder].site.name).to.equal(sampleOrtbConfig.site.name)
+ expect(bidderConfig[bidder].user.keywords).to.equal(sampleOrtbConfig.user.keywords)
+ expect(bidderConfig[bidder].user.data).to.deep.include.members([sampleOrtbConfig.user.data[0]])
})
})
})
diff --git a/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js b/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js
new file mode 100644
index 00000000000..49b048f1fe6
--- /dev/null
+++ b/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js
@@ -0,0 +1,70 @@
+import pianoDmpAnalytics from 'modules/pianoDmpAnalyticsAdapter.js';
+import adapterManager from 'src/adapterManager';
+import * as events from 'src/events';
+import constants from 'src/constants.json';
+import { expect } from 'chai';
+
+describe('Piano DMP Analytics Adapter', () => {
+ let sandbox;
+
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+
+ sandbox.stub(events, 'getEvents').returns([]);
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ describe('track', () => {
+ beforeEach(() => {
+ adapterManager.enableAnalytics({
+ provider: 'pianoDmp',
+ });
+ });
+
+ afterEach(() => {
+ delete window.cX;
+ pianoDmpAnalytics.disableAnalytics();
+ });
+
+ it('should pass events to call queue', () => {
+ const eventsList = [
+ constants.EVENTS.AUCTION_INIT,
+ constants.EVENTS.AUCTION_END,
+ constants.EVENTS.BID_ADJUSTMENT,
+ constants.EVENTS.BID_TIMEOUT,
+ constants.EVENTS.BID_REQUESTED,
+ constants.EVENTS.BID_RESPONSE,
+ constants.EVENTS.NO_BID,
+ constants.EVENTS.BID_WON,
+ ];
+
+ // Given
+ const testEvents = eventsList.map((event) => ({
+ event,
+ args: { test: event },
+ }));
+
+ // When
+ testEvents.forEach(({ event, args }) => events.emit(event, args));
+
+ // Then
+ const callQueue = (window.cX || {}).callQueue;
+ const billableEventIndex = callQueue.findIndex(([, params]) => params.eventType === constants.EVENTS.BILLABLE_EVENT);
+ if (billableEventIndex > -1) {
+ callQueue.splice(billableEventIndex, 1);
+ }
+
+ expect(callQueue).to.be.an('array');
+ expect(callQueue.length).to.equal(testEvents.length);
+
+ callQueue.forEach(([method, params], index) => {
+ expect(method).to.equal('prebid');
+ expect(params.eventType).to.equal(testEvents[index].event);
+ expect(params.params).to.deep.equal(testEvents[index].args);
+ });
+ });
+ });
+});
diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js
index 434f668aad0..ff600d4ef93 100644
--- a/test/spec/modules/prebidServerBidAdapter_spec.js
+++ b/test/spec/modules/prebidServerBidAdapter_spec.js
@@ -87,6 +87,84 @@ const REQUEST = {
]
};
+const NATIVE_ORTB_MTO = {
+ ortb: {
+ context: 3,
+ plcmttype: 2,
+ eventtrackers: [
+ {
+ event: 1,
+ methods: [
+ 1
+ ]
+ },
+ {
+ event: 2,
+ methods: [
+ 2
+ ]
+ }
+ ],
+ assets: [
+ {
+ id: 1,
+ required: 1,
+ img: {
+ type: 3,
+ w: 300,
+ h: 250
+ }
+ },
+ {
+ id: 2,
+ required: 1,
+ img: {
+ type: 1,
+ w: 127,
+ h: 83
+ }
+ },
+ {
+ id: 3,
+ required: 1,
+ data: {
+ type: 1,
+ len: 25
+ }
+ },
+ {
+ id: 4,
+ required: 1,
+ title: {
+ len: 140
+ }
+ },
+ {
+ id: 5,
+ required: 1,
+ data: {
+ type: 2,
+ len: 40
+ }
+ },
+ {
+ id: 6,
+ required: 1,
+ data: {
+ type: 12,
+ len: 15
+ }
+ },
+ ],
+ ext: {
+ custom_param: {
+ key: 'custom_value'
+ }
+ },
+ ver: '1.2'
+ }
+}
+
const VIDEO_REQUEST = {
'account_id': '1',
'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5',
@@ -501,8 +579,7 @@ describe('S2S Adapter', function () {
'sizes': [300, 250],
'bidId': '123',
'bidderRequestId': '3d1063078dfcc8',
- 'auctionId': '173afb6d132ba3',
- 'storedAuctionResponse': 11111
+ 'auctionId': '173afb6d132ba3'
}
],
'auctionStart': 1510852447530,
@@ -510,7 +587,7 @@ describe('S2S Adapter', function () {
'src': 's2s',
'doneCbCallCount': 0,
'refererInfo': {
- 'referer': 'http://mytestpage.com'
+ 'page': 'http://mytestpage.com'
}
}
];
@@ -645,6 +722,14 @@ describe('S2S Adapter', function () {
expect(adapter.callBids).to.exist.and.to.be.a('function');
});
+ function mockConsent({applies = true, hasP1Consent = true} = {}) {
+ return {
+ consentString: 'mockConsent',
+ gdprApplies: applies,
+ vendorData: {purpose: {consents: {1: hasP1Consent}}},
+ }
+ }
+
describe('gdpr tests', function () {
afterEach(function () {
$$PREBID_GLOBAL$$.requestBids.removeAll();
@@ -655,16 +740,13 @@ describe('S2S Adapter', function () {
config.setConfig(consentConfig);
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
- gdprBidRequest[0].gdprConsent = {
- consentString: 'abc123',
- gdprApplies: true
- };
+ gdprBidRequest[0].gdprConsent = mockConsent();
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.consent).is.equal('mockConsent');
config.resetConfig();
config.setConfig({ s2sConfig: CONFIG });
@@ -681,17 +763,15 @@ describe('S2S Adapter', function () {
config.setConfig(consentConfig);
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
- gdprBidRequest[0].gdprConsent = {
- consentString: 'abc123',
+ gdprBidRequest[0].gdprConsent = Object.assign(mockConsent(), {
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.consent).is.equal('mockConsent');
expect(requestBid.user.ext.ConsentedProvidersSettings.consented_providers).is.equal('superduperconsent');
config.resetConfig();
@@ -713,10 +793,7 @@ describe('S2S Adapter', function () {
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
- gdprBidRequest[0].gdprConsent = {
- consentString: 'abc123def',
- gdprApplies: true
- };
+ gdprBidRequest[0].gdprConsent = mockConsent();
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
@@ -725,7 +802,7 @@ describe('S2S Adapter', function () {
let requestBid = JSON.parse(server.requests[0].requestBody);
expect(requestBid.gdpr).is.equal(1);
- expect(requestBid.gdpr_consent).is.equal('abc123def');
+ expect(requestBid.gdpr_consent).is.equal('mockConsent');
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
});
@@ -741,10 +818,7 @@ describe('S2S Adapter', function () {
s2sBidRequest.s2sConfig = cookieSyncConfig;
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
- gdprBidRequest[0].gdprConsent = {
- consentString: 'xyz789abcc',
- gdprApplies: false
- };
+ gdprBidRequest[0].gdprConsent = mockConsent({applies: false});
adapter.callBids(s2sBidRequest, gdprBidRequest, addBidResponse, done, ajax);
let requestBid = JSON.parse(server.requests[0].requestBody);
@@ -761,10 +835,7 @@ describe('S2S Adapter', function () {
config.setConfig(consentConfig);
let gdprBidRequest = utils.deepClone(BID_REQUESTS);
- gdprBidRequest[0].gdprConsent = {
- consentString: undefined,
- gdprApplies: false
- };
+ gdprBidRequest[0].gdprConsent = mockConsent({applies: false});
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig;
@@ -832,17 +903,14 @@ describe('S2S Adapter', function () {
let consentBidRequest = utils.deepClone(BID_REQUESTS);
consentBidRequest[0].uspConsent = '1NYN';
- consentBidRequest[0].gdprConsent = {
- consentString: 'abc123',
- gdprApplies: true
- };
+ consentBidRequest[0].gdprConsent = mockConsent();
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');
+ expect(requestBid.user.ext.consent).is.equal('mockConsent');
config.resetConfig();
config.setConfig({ s2sConfig: CONFIG });
@@ -861,10 +929,7 @@ describe('S2S Adapter', function () {
let consentBidRequest = utils.deepClone(BID_REQUESTS);
consentBidRequest[0].uspConsent = '1YNN';
- consentBidRequest[0].gdprConsent = {
- consentString: 'abc123def',
- gdprApplies: true
- };
+ consentBidRequest[0].gdprConsent = mockConsent();
const s2sBidRequest = utils.deepClone(REQUEST);
s2sBidRequest.s2sConfig = cookieSyncConfig
@@ -874,7 +939,7 @@ describe('S2S Adapter', function () {
expect(requestBid.us_privacy).is.equal('1YNN');
expect(requestBid.gdpr).is.equal(1);
- expect(requestBid.gdpr_consent).is.equal('abc123def');
+ expect(requestBid.gdpr_consent).is.equal('mockConsent');
expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1);
expect(requestBid.account).is.equal('1');
});
@@ -928,24 +993,6 @@ describe('S2S Adapter', function () {
});
});
- 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);
@@ -1227,7 +1274,7 @@ describe('S2S Adapter', function () {
} else {
delete getGlobal().convertCurrency;
}
- })
+ });
it(`should pick the ${expectDesc}`, () => {
adapter.callBids(s2sReq, BID_REQUESTS, addBidResponse, done, ajax);
@@ -1240,96 +1287,119 @@ describe('S2S Adapter', function () {
});
});
- 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' }
- });
- });
+ if (FEATURES.NATIVE) {
+ describe('native requests', function () {
+ 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' },
+ };
- 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.device).to.deep.equal({
+ w: window.innerWidth,
+ h: window.innerHeight
+ });
+ expect(requestBid.app).to.deep.equal({
+ bundle: 'com.test.app',
+ publisher: { 'id': '1' }
+ });
+ });
- config.setConfig(_config);
- adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
- const requestBid = JSON.parse(server.requests[0].requestBody);
+ it('adds native request for OpenRTB', function () {
+ const _config = {
+ s2sConfig: CONFIG
+ };
- expect(requestBid.imp[0].native).to.deep.equal({
- request: JSON.stringify({
- 'context': 1,
- 'plcmttype': 1,
- 'eventtrackers': [{
- event: 1,
- methods: [1]
- }],
- 'assets': [
- {
- 'required': 1,
- 'id': 0,
- 'title': {
- 'len': 800
- }
- },
- {
- 'required': 1,
- 'id': 1,
- 'img': {
- 'type': 3,
- 'w': 989,
- 'h': 742
- }
- },
- {
- 'required': 1,
- 'id': 2,
- 'img': {
- 'type': 1,
- 'wmin': 10,
- 'hmin': 10,
- 'ext': {
- 'aspectratios': ['1:1']
+ config.setConfig(_config);
+ adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
+ const requestBid = JSON.parse(server.requests[0].requestBody);
+ const ortbReq = JSON.parse(requestBid.imp[0].native.request);
+ expect(ortbReq).to.deep.equal({
+ 'ver': '1.2',
+ 'context': 1,
+ 'plcmttype': 1,
+ 'eventtrackers': [{
+ event: 1,
+ methods: [1]
+ }],
+ 'assets': [
+ {
+ 'required': 1,
+ 'id': 0,
+ 'title': {
+ 'len': 800
+ }
+ },
+ {
+ 'required': 1,
+ 'id': 1,
+ 'img': {
+ 'type': 3,
+ 'w': 989,
+ 'h': 742
+ }
+ },
+ {
+ 'required': 1,
+ 'id': 2,
+ 'img': {
+ 'type': 1,
+ 'wmin': 10,
+ 'hmin': 10,
+ 'ext': {
+ 'aspectratios': ['1:1']
+ }
+ }
+ },
+ {
+ 'required': 1,
+ 'id': 3,
+ 'data': {
+ 'type': 1
}
}
- },
- {
- 'required': 1,
- 'id': 3,
- 'data': {
- 'type': 1
- }
- }
- ]
- }),
- ver: '1.2'
- });
- });
+ ]
+ });
+ expect(requestBid.imp[0].native.ver).to.equal('1.2');
+ });
+
+ it('adds native ortb request for OpenRTB', function () {
+ const _config = {
+ s2sConfig: CONFIG
+ };
+
+ const openRtbNativeRequest = deepClone(REQUEST);
+ delete openRtbNativeRequest.ad_units[0].mediaTypes.native;
+ delete openRtbNativeRequest.ad_units[0].nativeParams;
+
+ openRtbNativeRequest.ad_units[0].mediaTypes.native = NATIVE_ORTB_MTO;
+ prepRequest(openRtbNativeRequest);
- it('should not include ext.aspectratios if adunit\'s aspect_ratios do not define radio_width and ratio_height', () => {
- const req = deepClone(REQUEST);
- req.ad_units[0].mediaTypes.native.icon.aspect_ratios[0] = { 'min_width': 1, 'min_height': 2 };
- prepRequest(req);
- adapter.callBids(req, BID_REQUESTS, addBidResponse, done, ajax);
- const nativeReq = JSON.parse(JSON.parse(server.requests[0].requestBody).imp[0].native.request);
- const icons = nativeReq.assets.map((a) => a.img).filter((img) => img && img.type === 1);
- expect(icons).to.have.length(1);
- expect(icons[0].hmin).to.equal(2);
- expect(icons[0].wmin).to.equal(1);
- expect(deepAccess(icons[0], 'ext.aspectratios')).to.be.undefined;
- })
+ config.setConfig(_config);
+ adapter.callBids(openRtbNativeRequest, BID_REQUESTS, addBidResponse, done, ajax);
+ const requestBid = JSON.parse(server.requests[0].requestBody);
+ const nativeReq = JSON.parse(requestBid.imp[0].native.request);
+ expect(nativeReq).to.deep.equal(NATIVE_ORTB_MTO.ortb);
+ expect(requestBid.imp[0].native.ver).to.equal('1.2');
+ });
+
+ it('should not include ext.aspectratios if adunit\'s aspect_ratios do not define radio_width and ratio_height', () => {
+ const req = deepClone(REQUEST);
+ req.ad_units[0].mediaTypes.native.icon.aspect_ratios[0] = {'min_width': 1, 'min_height': 2};
+ prepRequest(req);
+ adapter.callBids(req, BID_REQUESTS, addBidResponse, done, ajax);
+ const nativeReq = JSON.parse(JSON.parse(server.requests[0].requestBody).imp[0].native.request);
+ const icons = nativeReq.assets.map((a) => a.img).filter((img) => img && img.type === 1);
+ expect(icons).to.have.length(1);
+ expect(icons[0].hmin).to.equal(2);
+ expect(icons[0].wmin).to.equal(1);
+ expect(deepAccess(icons[0], 'ext.aspectratios')).to.be.undefined;
+ });
+ });
+ }
it('adds site if app is not present', function () {
const _config = {
@@ -1371,7 +1441,7 @@ describe('S2S Adapter', function () {
config.setConfig({ s2sConfig: CONFIG });
const aliasBidder = {
- bidder: 'brealtime',
+ bidder: 'beintoo',
params: { placementId: '123456' }
};
@@ -1384,7 +1454,7 @@ describe('S2S Adapter', function () {
expect(requestBid.ext).to.haveOwnProperty('prebid');
expect(requestBid.ext.prebid).to.deep.include({
aliases: {
- brealtime: 'appnexus'
+ beintoo: 'appnexus'
},
auctiontimestamp: 1510852447530,
targeting: {
@@ -1521,11 +1591,12 @@ describe('S2S Adapter', function () {
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([{
+ const requestParams = requestBid.imp[0].ext.prebid.bidder;
+ expect(requestParams.appnexus).to.exist;
+ expect(requestParams.appnexus.placement_id).to.exist.and.to.equal(10433394);
+ expect(requestParams.appnexus.use_pmt_rule).to.exist.and.to.be.true;
+ expect(requestParams.appnexus.member).to.exist;
+ expect(requestParams.appnexus.keywords).to.exist.and.to.deep.equal([{
key: 'foo',
value: ['bar', 'baz']
}, {
@@ -1605,8 +1676,9 @@ describe('S2S Adapter', function () {
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')
+ const requestParams = requestBid.imp[0].ext.prebid.bidder;
+ expect(requestParams.appnexus).to.haveOwnProperty('key');
+ expect(requestParams.appnexus.key).to.be.equal('value')
});
describe('config site value is added to the oRTB request', function () {
@@ -1902,6 +1974,163 @@ describe('S2S Adapter', function () {
});
});
+ it('should have extPrebid.schains present on req object if bidder specific schains were configured with pbjs', function () {
+ let bidRequest = utils.deepClone(BID_REQUESTS);
+ bidRequest[0].bids[0].schain = {
+ complete: 1,
+ nodes: [{
+ asi: 'test.com',
+ hp: 1,
+ sid: '11111'
+ }],
+ ver: '1.0'
+ };
+
+ adapter.callBids(REQUEST, bidRequest, addBidResponse, done, ajax);
+ let requestBid = JSON.parse(server.requests[0].requestBody);
+
+ expect(requestBid.ext.prebid.schains).to.deep.equal([
+ {
+ bidders: ['appnexus'],
+ schain: {
+ complete: 1,
+ nodes: [
+ {
+ asi: 'test.com',
+ hp: 1,
+ sid: '11111'
+ }
+ ],
+ ver: '1.0'
+ }
+ }
+ ]);
+ });
+
+ it('should skip over adding any bid specific schain entries that already exist on extPrebid.schains', function () {
+ let bidRequest = utils.deepClone(BID_REQUESTS);
+ bidRequest[0].bids[0].schain = {
+ complete: 1,
+ nodes: [{
+ asi: 'pbjs.com',
+ hp: 1,
+ sid: '22222'
+ }],
+ ver: '1.0'
+ };
+
+ const s2sConfig = Object.assign({}, CONFIG, {
+ extPrebid: {
+ schains: [
+ {
+ bidders: ['appnexus'],
+ schain: {
+ complete: 1,
+ nodes: [
+ {
+ asi: 'pbs.com',
+ hp: 1,
+ sid: '11111'
+ }
+ ],
+ ver: '1.0'
+ }
+ }
+ ]
+ }
+ });
+
+ const s2sBidRequest = utils.deepClone(REQUEST);
+ s2sBidRequest.s2sConfig = s2sConfig;
+
+ adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax);
+
+ let requestBid = JSON.parse(server.requests[0].requestBody);
+ expect(requestBid.ext.prebid.schains).to.deep.equal([
+ {
+ bidders: ['appnexus'],
+ schain: {
+ complete: 1,
+ nodes: [
+ {
+ asi: 'pbs.com',
+ hp: 1,
+ sid: '11111'
+ }
+ ],
+ ver: '1.0'
+ }
+ }
+ ]);
+ });
+
+ it('should add a bidder name to pbs schain if the schain is equal to a pbjs one but the pbjs bidder name is not in the bidder array on the pbs side', function () {
+ let bidRequest = utils.deepClone(BID_REQUESTS);
+ bidRequest[0].bids[0].schain = {
+ complete: 1,
+ nodes: [{
+ asi: 'test.com',
+ hp: 1,
+ sid: '11111'
+ }],
+ ver: '1.0'
+ };
+
+ bidRequest[0].bids[1] = {
+ bidder: 'rubicon',
+ params: {
+ accountId: 14062,
+ siteId: 70608,
+ zoneId: 498816
+ }
+ };
+
+ const s2sConfig = Object.assign({}, CONFIG, {
+ bidders: ['rubicon', 'appnexus'],
+ extPrebid: {
+ schains: [
+ {
+ bidders: ['rubicon'],
+ schain: {
+ complete: 1,
+ nodes: [
+ {
+ asi: 'test.com',
+ hp: 1,
+ sid: '11111'
+ }
+ ],
+ ver: '1.0'
+ }
+ }
+ ]
+ }
+ });
+
+ const s2sBidRequest = utils.deepClone(REQUEST);
+ s2sBidRequest.s2sConfig = s2sConfig;
+
+ adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax);
+
+ let requestBid = JSON.parse(server.requests[0].requestBody);
+ expect(requestBid.ext.prebid.schains).to.deep.equal([
+ {
+ bidders: ['rubicon', 'appnexus'],
+ schain: {
+ complete: 1,
+ nodes: [
+ {
+ asi: 'test.com',
+ hp: 1,
+ sid: '11111'
+ }
+ ],
+ ver: '1.0'
+ }
+ }
+ ]);
+ });
+
it('passes schain object in request', function () {
const bidRequests = utils.deepClone(BID_REQUESTS);
const schainObject = {
@@ -1983,7 +2212,7 @@ describe('S2S Adapter', function () {
const s2sBidRequest = utils.deepClone(REQUEST);
const bidRequests = utils.deepClone(BID_REQUESTS);
- const commonContext = {
+ const commonSite = {
keywords: ['power tools'],
search: 'drill'
};
@@ -1992,19 +2221,23 @@ describe('S2S Adapter', function () {
gender: 'M'
};
- const context = {
- content: { userrating: 4 },
- data: {
- pageType: 'article',
- category: 'tools'
+ const site = {
+ content: {userrating: 4},
+ ext: {
+ data: {
+ pageType: 'article',
+ category: 'tools'
+ }
}
};
const user = {
yob: '1984',
geo: { country: 'ca' },
- data: {
- registered: true,
- interests: ['cars']
+ ext: {
+ data: {
+ registered: true,
+ interests: ['cars']
+ }
}
};
const bcat = ['IAB25', 'IAB7-39'];
@@ -2042,11 +2275,14 @@ describe('S2S Adapter', function () {
const commonContextExpected = utils.mergeDeep({
'page': 'http://mytestpage.com',
'publisher': { 'id': '1' }
- }, commonContext);
+ }, commonSite);
- config.setConfig({ fpd: { context: commonContext, user: commonUser, badv, bcat } });
- config.setBidderConfig({ bidders: allowedBidders, config: { fpd: { context, user, bcat, badv } } });
- adapter.callBids(s2sBidRequest, bidRequests, addBidResponse, done, ajax);
+ const ortb2Fragments = {
+ global: {site: commonSite, user: commonUser, badv, bcat},
+ bidder: Object.fromEntries(allowedBidders.map(bidder => [bidder, {site, user, bcat, badv}]))
+ };
+
+ adapter.callBids({...s2sBidRequest, ortb2Fragments}, bidRequests, addBidResponse, done, ajax);
const parsedRequestBody = JSON.parse(server.requests[0].requestBody);
expect(parsedRequestBody.ext.prebid.bidderconfig).to.deep.equal(expected);
expect(parsedRequestBody.site).to.deep.equal(commonContextExpected);
@@ -2638,33 +2874,35 @@ describe('S2S Adapter', function () {
expect(response).to.have.property('pbsBidId', '654321');
});
- it('handles OpenRTB native responses', function () {
- const stub = sinon.stub(auctionManager, 'index');
- stub.get(() => stubAuctionIndex({ adUnits: REQUEST.ad_units }));
- const s2sConfig = Object.assign({}, CONFIG, {
- endpoint: {
- p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param'
- }
- });
- config.setConfig({ s2sConfig });
+ if (FEATURES.NATIVE) {
+ it('handles OpenRTB native responses', function () {
+ const stub = sinon.stub(auctionManager, 'index');
+ stub.get(() => stubAuctionIndex({adUnits: REQUEST.ad_units}));
+ const s2sConfig = Object.assign({}, CONFIG, {
+ endpoint: {
+ p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param'
+ }
+ });
+ config.setConfig({s2sConfig});
- const s2sBidRequest = utils.deepClone(REQUEST);
- s2sBidRequest.s2sConfig = s2sConfig;
+ const s2sBidRequest = utils.deepClone(REQUEST);
+ s2sBidRequest.s2sConfig = s2sConfig;
- adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax);
- server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB_NATIVE));
+ adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax);
+ server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB_NATIVE));
- sinon.assert.calledOnce(addBidResponse);
- const response = addBidResponse.firstCall.args[1];
- expect(response).to.have.property('statusMessage', 'Bid available');
- expect(response).to.have.property('adm').deep.equal(RESPONSE_OPENRTB_NATIVE.seatbid[0].bid[0].adm);
- expect(response).to.have.property('mediaType', 'native');
- expect(response).to.have.property('bidderCode', 'appnexus');
- expect(response).to.have.property('requestId', '123');
- expect(response).to.have.property('cpm', 10);
+ sinon.assert.calledOnce(addBidResponse);
+ const response = addBidResponse.firstCall.args[1];
+ expect(response).to.have.property('statusMessage', 'Bid available');
+ expect(response).to.have.property('adm').deep.equal(RESPONSE_OPENRTB_NATIVE.seatbid[0].bid[0].adm);
+ expect(response).to.have.property('mediaType', 'native');
+ expect(response).to.have.property('bidderCode', 'appnexus');
+ expect(response).to.have.property('requestId', '123');
+ expect(response).to.have.property('cpm', 10);
- stub.restore();
- });
+ stub.restore();
+ });
+ }
it('does not (by default) allow bids that were not requested', function () {
config.setConfig({ s2sConfig: CONFIG });
@@ -2710,6 +2948,26 @@ describe('S2S Adapter', function () {
sinon.assert.match(actual.imp[0], sinon.match(ortb2Imp));
});
+ it('setting adapterCode for default bidder', function () {
+ config.setConfig({ CONFIG });
+ adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
+ server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB));
+
+ const response = addBidResponse.firstCall.args[1];
+ expect(response).to.have.property('adapterCode', 'appnexus');
+ });
+
+ it('setting adapterCode for alternate bidder', function () {
+ config.setConfig({ CONFIG });
+ let RESPONSE_OPENRTB2 = deepClone(RESPONSE_OPENRTB);
+ RESPONSE_OPENRTB2.seatbid[0].bid[0].ext.prebid.meta.adaptercode = 'appnexus2'
+ adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax);
+ server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB2));
+
+ const response = addBidResponse.firstCall.args[1];
+ expect(response).to.have.property('adapterCode', 'appnexus2');
+ });
+
describe('on sync requested with no cookie', () => {
let cfg, req, csRes;
diff --git a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js b/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js
index e504eced868..2e1bf4df062 100644
--- a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js
+++ b/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js
@@ -102,7 +102,8 @@ describe('Prebid Manager Analytics Adapter', function () {
events.emit(constants.EVENTS.AUCTION_END, {});
events.emit(constants.EVENTS.BID_TIMEOUT, {});
- sinon.assert.callCount(prebidmanagerAnalytics.track, 6);
+ // 6 Prebid Manager events + 1 Clean.io event
+ sinon.assert.callCount(prebidmanagerAnalytics.track, 7);
});
});
diff --git a/test/spec/modules/prismaBidAdapter_spec.js b/test/spec/modules/prismaBidAdapter_spec.js
new file mode 100644
index 00000000000..be1c16c9059
--- /dev/null
+++ b/test/spec/modules/prismaBidAdapter_spec.js
@@ -0,0 +1,261 @@
+import {expect} from 'chai';
+import {spec} from 'modules/prismaBidAdapter.js';
+import {newBidder} from 'src/adapters/bidderFactory.js';
+import {config} from 'src/config.js';
+import * as utils from 'src/utils.js';
+import { requestBidsHook } from 'modules/consentManagement.js';
+
+describe('Prisma bid adapter tests', function () {
+ const DISPLAY_BID_REQUEST = [{
+ 'bidder': 'prisma',
+ 'params': {
+ 'account': '1067',
+ 'tagId': 'luvxjvgn'
+ },
+ 'userId': {
+ 'id5id': {
+ 'uid': 'ID5*hQ5WobYI9Od4u52qpaXVKHhxUa4DsOWRAlvaFajm8gINfI1oVAe3UK59416dT4TqDX1pj4MBJ5TYwir6x3JgBw1-avYHSnmvQDdRMbxmC2sNf3ggIRTbyQBdI1RjvHyeDYCsistnTXF_iKF1nutYeQ2BZ4P5d5muZTG7C2PXVFgNg-18io9dCiSjzJXx93KPDYRiuIwtsGGsp51rojlpFw2Fp_dUkjXl4CAblk58DvwNhobwQ27bnBP8F2-Pcs88DYcvKn4r6dm3Vi7ILttxDQ2IgZ2X44ClgjoWh-vRf6ANis8Z7uL16vO8q0P5C21eDYuc4v_KaZqN-p9YWEeEZQ2OpkbRL7n5NieVJExHM6ANkAlLZhVf2T-1906TAIHKDZFm_xMCa1jJfpBqZB2agw2TjfbK6wMtJeHiZaipSuUNlM_CSH0HVXtfMj9yfzjzDZZnltZQ9lvc4JhXye5AwA2X1f9Dhk8VURTvVdfEUlU',
+ 'ext': {
+ 'linkType': 2
+ }
+ }
+ },
+ 'userIdAsEids': [
+ {
+ 'source': 'id5-sync.com',
+ 'uids': [
+ {
+ 'id': 'ID5*hQ5WobYI9Od4u52qpaXVKHhxUa4DsOWRAlvaFajm8gINfI1oVAe3UK59416dT4TqDX1pj4MBJ5TYwir6x3JgBw1-avYHSnmvQDdRMbxmC2sNf3ggIRTbyQBdI1RjvHyeDYCsistnTXF_iKF1nutYeQ2BZ4P5d5muZTG7C2PXVFgNg-18io9dCiSjzJXx93KPDYRiuIwtsGGsp51rojlpFw2Fp_dUkjXl4CAblk58DvwNhobwQ27bnBP8F2-Pcs88DYcvKn4r6dm3Vi7ILttxDQ2IgZ2X44ClgjoWh-vRf6ANis8Z7uL16vO8q0P5C21eDYuc4v_KaZqN-p9YWEeEZQ2OpkbRL7n5NieVJExHM6ANkAlLZhVf2T-1906TAIHKDZFm_xMCa1jJfpBqZB2agw2TjfbK6wMtJeHiZaipSuUNlM_CSH0HVXtfMj9yfzjzDZZnltZQ9lvc4JhXye5AwA2X1f9Dhk8VURTvVdfEUlU',
+ 'atype': 1,
+ 'ext': {
+ 'linkType': 2
+ }
+ }
+ ]
+ }
+ ],
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[300, 250], [300, 600]]
+ }
+ },
+ 'adUnitCode': 'banner-div',
+ 'transactionId': '9ad89d90-eb73-41b9-bf5f-7a8e2eecff27',
+ 'sizes': [[300, 250], [300, 600]],
+ 'bidId': '4d9e29504f8af6',
+ 'bidderRequestId': '3423b6bd1a922c',
+ 'auctionId': '05e0a3a1-9f57-41f6-bbcb-2ba9c9e3d2d5',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ }];
+
+ const DISPLAY_BID_RESPONSE = {'body': {
+ 'responses': [
+ {
+ 'bidId': '4d9e29504f8af6',
+ 'cpm': 0.437245,
+ 'width': 300,
+ 'height': 250,
+ 'creativeId': '98493581',
+ 'currency': 'EUR',
+ 'netRevenue': true,
+ 'type': 'banner',
+ 'ttl': 360,
+ 'uuid': 'ce6d1ee3-2a05-4d7c-b97a-9e62097798ec',
+ 'bidder': 'appnexus',
+ 'consent': 1,
+ 'tagId': 'luvxjvgn'
+ }
+ ],
+ }};
+
+ const VIDEO_BID_REQUEST = [
+ {
+ 'bidder': 'prisma',
+ 'params': {
+ 'account': '1067',
+ 'tagId': 'yqsc1tfj'
+ },
+ 'mediaTypes': {
+ 'video': {
+ 'context': 'instream',
+ 'playerSize': [[640, 480]],
+ 'mimes': ['video/mp4'],
+ 'protocols': [1, 2, 3, 4, 5, 6],
+ 'playbackmethod': [2],
+ 'skip': 1
+ }
+ },
+ 'adUnitCode': 'video1',
+ 'transactionId': '5434c81c-7210-44ae-9014-67c75dee48d0',
+ 'sizes': [[640, 480]],
+ 'bidId': '22f90541e576a3',
+ 'bidderRequestId': '1d4549243f3bfd',
+ 'auctionId': 'ed21b528-bcab-47e2-8605-ec9b71000c89',
+ 'src': 'client',
+ 'bidRequestsCount': 1,
+ 'bidderRequestsCount': 1,
+ 'bidderWinsCount': 0
+ }
+ ]
+
+ const VIDEO_BID_RESPONSE = {'body': {
+ 'responses': [
+ {
+ 'bidId': '2c129e8e01859a',
+ 'type': 'video',
+ 'uuid': 'b8e7b2f0-c378-479f-aa4f-4f55d5d7d1d5',
+ 'cpm': 4.5421,
+ 'width': 1,
+ 'height': 1,
+ 'creativeId': '97517771',
+ 'currency': 'EUR',
+ 'netRevenue': true,
+ 'ttl': 360,
+ 'bidder': 'appnexus',
+ 'consent': 1,
+ 'tagId': 'yqsc1tfj'
+ }
+ ]
+ }};
+
+ const DEFAULT_OPTIONS = {
+ gdprConsent: {
+ gdprApplies: true,
+ consentString: 'BOzZdA0OzZdA0AGABBENDJ-AAAAvh7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__79__3z3_9pxP78k89r7337Mw_v-_v-b7JCPN_Y3v-8Kg',
+ vendorData: {}
+ },
+ refererInfo: {
+ referer: 'https://www.prebid.org',
+ canonicalUrl: 'https://www.prebid.org/the/link/to/the/page'
+ },
+ uspConsent: '111222333',
+ userId: { 'id5id': { uid: '1111' } },
+ schain: {
+ 'ver': '1.0',
+ 'complete': 1,
+ 'nodes': [{
+ 'asi': 'exchange1.com',
+ 'sid': '1234',
+ 'hp': 1,
+ 'rid': 'bid-request-1',
+ 'name': 'publisher',
+ 'domain': 'publisher.com'
+ }]
+ },
+ };
+
+ it('Verify banner build request', function () {
+ const request = spec.buildRequests(DISPLAY_BID_REQUEST, DEFAULT_OPTIONS);
+ expect(request).to.have.property('url').and.to.equal('https://prisma.nexx360.io/prebid');
+ expect(request).to.have.property('method').and.to.equal('POST');
+ const requestContent = JSON.parse(request.data);
+ expect(requestContent.userEids.length).to.be.eql(1);
+ expect(requestContent.userEids[0]).to.have.property('source').and.to.equal('id5-sync.com');
+ expect(requestContent.userEids[0]).to.have.property('uids');
+ expect(requestContent.userEids[0].uids[0]).to.have.property('id').and.to.equal('ID5*hQ5WobYI9Od4u52qpaXVKHhxUa4DsOWRAlvaFajm8gINfI1oVAe3UK59416dT4TqDX1pj4MBJ5TYwir6x3JgBw1-avYHSnmvQDdRMbxmC2sNf3ggIRTbyQBdI1RjvHyeDYCsistnTXF_iKF1nutYeQ2BZ4P5d5muZTG7C2PXVFgNg-18io9dCiSjzJXx93KPDYRiuIwtsGGsp51rojlpFw2Fp_dUkjXl4CAblk58DvwNhobwQ27bnBP8F2-Pcs88DYcvKn4r6dm3Vi7ILttxDQ2IgZ2X44ClgjoWh-vRf6ANis8Z7uL16vO8q0P5C21eDYuc4v_KaZqN-p9YWEeEZQ2OpkbRL7n5NieVJExHM6ANkAlLZhVf2T-1906TAIHKDZFm_xMCa1jJfpBqZB2agw2TjfbK6wMtJeHiZaipSuUNlM_CSH0HVXtfMj9yfzjzDZZnltZQ9lvc4JhXye5AwA2X1f9Dhk8VURTvVdfEUlU');
+ expect(requestContent.adUnits[0]).to.have.property('account').and.to.equal('1067');
+ expect(requestContent.adUnits[0]).to.have.property('tagId').and.to.equal('luvxjvgn');
+ expect(requestContent.adUnits[0]).to.have.property('label').and.to.equal('banner-div');
+ expect(requestContent.adUnits[0]).to.have.property('bidId').and.to.equal('4d9e29504f8af6');
+ expect(requestContent.adUnits[0]).to.have.property('auctionId').and.to.equal('05e0a3a1-9f57-41f6-bbcb-2ba9c9e3d2d5');
+ expect(requestContent.adUnits[0]).to.have.property('mediatypes').exist;
+ expect(requestContent.adUnits[0].mediatypes).to.have.property('banner').exist;
+ expect(requestContent.adUnits[0]).to.have.property('bidfloor').and.to.equal(0);
+ expect(requestContent.adUnits[0]).to.have.property('bidfloorCurrency').and.to.equal('USD');
+ expect(requestContent.adUnits[0]).to.have.property('keywords');
+ expect(requestContent.adUnits[0].keywords.length).to.be.eql(0);
+ });
+
+ it('Verify banner parse response', function () {
+ const request = spec.buildRequests(DISPLAY_BID_REQUEST, DEFAULT_OPTIONS);
+ const response = spec.interpretResponse(DISPLAY_BID_RESPONSE, request);
+ expect(response).to.have.lengthOf(1);
+ const bid = response[0];
+ expect(bid.cpm).to.equal(0.437245);
+ expect(bid.adUrl).to.equal('https://prisma.nexx360.io/cache?uuid=ce6d1ee3-2a05-4d7c-b97a-9e62097798ec');
+ expect(bid.width).to.equal(300);
+ expect(bid.height).to.equal(250);
+ expect(bid.creativeId).to.equal('98493581');
+ expect(bid.currency).to.equal('EUR');
+ expect(bid.netRevenue).to.equal(true);
+ expect(bid.ttl).to.equal(360);
+ expect(bid.requestId).to.equal('4d9e29504f8af6');
+ expect(bid.prisma).to.exist;
+ expect(bid.prisma.ssp).to.equal('appnexus');
+ });
+
+ it('Verify video build request', function () {
+ const request = spec.buildRequests(VIDEO_BID_REQUEST, DEFAULT_OPTIONS);
+ expect(request).to.have.property('url').and.to.equal('https://prisma.nexx360.io/prebid');
+ expect(request).to.have.property('method').and.to.equal('POST');
+ const requestContent = JSON.parse(request.data);
+ expect(requestContent.adUnits[0]).to.have.property('account').and.to.equal('1067');
+ expect(requestContent.adUnits[0]).to.have.property('tagId').and.to.equal('yqsc1tfj');
+ expect(requestContent.adUnits[0]).to.have.property('label').and.to.equal('video1');
+ expect(requestContent.adUnits[0]).to.have.property('bidId').and.to.equal('22f90541e576a3');
+ expect(requestContent.adUnits[0]).to.have.property('auctionId').and.to.equal('ed21b528-bcab-47e2-8605-ec9b71000c89');
+ expect(requestContent.adUnits[0]).to.have.property('mediatypes').exist;
+ expect(requestContent.adUnits[0].mediatypes).to.have.property('video').exist;
+ });
+
+ it('Verify video parse response', function () {
+ const request = spec.buildRequests(VIDEO_BID_REQUEST, DEFAULT_OPTIONS);
+ const response = spec.interpretResponse(VIDEO_BID_RESPONSE, request);
+ expect(response).to.have.lengthOf(1);
+ const bid = response[0];
+ expect(bid.cpm).to.equal(4.5421);
+ expect(bid.vastUrl).to.equal('https://prisma.nexx360.io/cache?uuid=b8e7b2f0-c378-479f-aa4f-4f55d5d7d1d5');
+ expect(bid.vastImpUrl).to.equal('https://prisma.nexx360.io/track-imp?type=prebid&mediatype=video&ssp=appnexus&tag_id=yqsc1tfj&consent=1&price=4.5421');
+ expect(bid.width).to.equal(1);
+ expect(bid.height).to.equal(1);
+ expect(bid.creativeId).to.equal('97517771');
+ expect(bid.currency).to.equal('EUR');
+ expect(bid.netRevenue).to.equal(true);
+ expect(bid.ttl).to.equal(360);
+ expect(bid.requestId).to.equal('2c129e8e01859a');
+ expect(bid.prisma).to.exist;
+ expect(bid.prisma.ssp).to.equal('appnexus');
+ });
+
+ it('Verifies bidder code', function () {
+ expect(spec.code).to.equal('prisma');
+ });
+
+ it('Verifies bidder aliases', function () {
+ expect(spec.aliases).to.have.lengthOf(1);
+ expect(spec.aliases[0]).to.eql('prismadirect');
+ });
+ it('Verifies if bid request valid', function () {
+ expect(spec.isBidRequestValid(DISPLAY_BID_REQUEST[0])).to.equal(true);
+ });
+ it('Verifies bid won', function () {
+ const request = spec.buildRequests(DISPLAY_BID_REQUEST, DEFAULT_OPTIONS);
+ const response = spec.interpretResponse(DISPLAY_BID_RESPONSE, request);
+ const won = spec.onBidWon(response[0]);
+ expect(won).to.equal(true);
+ });
+ it('Verifies user sync without cookie in bid response', function () {
+ var syncs = spec.getUserSyncs({}, [DISPLAY_BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent);
+ expect(syncs).to.have.lengthOf(0);
+ });
+ it('Verifies user sync with cookies in bid response', function () {
+ DISPLAY_BID_RESPONSE.body.cookies = [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}];
+ var syncs = spec.getUserSyncs({}, [DISPLAY_BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent);
+ expect(syncs).to.have.lengthOf(1);
+ expect(syncs[0]).to.have.property('type').and.to.equal('image');
+ expect(syncs[0]).to.have.property('url').and.to.equal('http://www.cookie.sync.org/');
+ });
+ it('Verifies user sync with no bid response', function() {
+ var syncs = spec.getUserSyncs({}, null, DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent);
+ expect(syncs).to.have.lengthOf(0);
+ });
+ it('Verifies user sync with no bid body response', function() {
+ var syncs = spec.getUserSyncs({}, [], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent);
+ expect(syncs).to.have.lengthOf(0);
+ var syncs = spec.getUserSyncs({}, [{}], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent);
+ expect(syncs).to.have.lengthOf(0);
+ });
+});
diff --git a/test/spec/modules/pubgeniusBidAdapter_spec.js b/test/spec/modules/pubgeniusBidAdapter_spec.js
index 4599eb2a6fa..1d1b0e65ec8 100644
--- a/test/spec/modules/pubgeniusBidAdapter_spec.js
+++ b/test/spec/modules/pubgeniusBidAdapter_spec.js
@@ -239,17 +239,8 @@ describe('pubGENIUS adapter', () => {
expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest);
});
- it('should take pageUrl in config over referer in refererInfo', () => {
- config.setConfig({ pageUrl: 'http://pageurl.org' });
- bidderRequest.refererInfo.referer = 'http://referer.org';
- expectedRequest.data.site = { page: 'http://pageurl.org' };
-
- expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest);
- });
-
- it('should use canonical URL over referer in refererInfo', () => {
- bidderRequest.refererInfo.canonicalUrl = 'http://pageurl.org';
- bidderRequest.refererInfo.referer = 'http://referer.org';
+ it('should use page from refererInfo', () => {
+ bidderRequest.refererInfo.page = 'http://pageurl.org';
expectedRequest.data.site = { page: 'http://pageurl.org' };
expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest);
diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js
index 02b4c8d1905..fa4519c84e1 100755
--- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js
+++ b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js
@@ -149,7 +149,7 @@ const MOCK = {
],
'timeout': 3000,
'refererInfo': {
- 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
+ 'topmostLocation': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
}
}
],
@@ -207,7 +207,7 @@ const MOCK = {
'timeout': 5000,
'start': 1519149562216,
'refererInfo': {
- 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
+ 'topmostLocation': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
},
'gdprConsent': {
'consentString': 'here-goes-gdpr-consent-string',
diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js
index 5215afcdcd7..3f341fd259f 100644
--- a/test/spec/modules/pubmaticBidAdapter_spec.js
+++ b/test/spec/modules/pubmaticBidAdapter_spec.js
@@ -1,8 +1,9 @@
import {expect} from 'chai';
-import {spec, checkVideoPlacement} from 'modules/pubmaticBidAdapter.js';
+import {spec, checkVideoPlacement, _getDomainFromURL} from 'modules/pubmaticBidAdapter.js';
import * as utils from 'src/utils.js';
import {config} from 'src/config.js';
import { createEidsArray } from 'modules/userId/eids.js';
+import { bidderSettings } from 'src/bidderSettings.js';
const constants = require('src/constants.json');
describe('PubMatic adapter', function () {
@@ -1102,8 +1103,80 @@ describe('PubMatic adapter', function () {
expect(data.imp[0].ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr);
expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency);
expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain);
+ expect(data.ext.epoch).to.exist;
});
+ it('Set tmax from global config if not set by requestBids method', function() {
+ let sandbox = sinon.sandbox.create();
+ sandbox.stub(config, 'getConfig').callsFake((key) => {
+ var config = {
+ bidderTimeout: 3000
+ };
+ return config[key];
+ });
+ let request = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id', timeout: 3000
+ });
+ let data = JSON.parse(request.data);
+ expect(data.tmax).to.deep.equal(3000);
+ sandbox.restore();
+ });
+ describe('Marketplace parameters', function() {
+ let bidderSettingStub;
+ beforeEach(function() {
+ bidderSettingStub = sinon.stub(bidderSettings, 'get');
+ });
+
+ afterEach(function() {
+ bidderSettingStub.restore();
+ });
+
+ it('should not be present when allowAlternateBidderCodes is undefined', function () {
+ bidderSettingStub.returns(undefined);
+ let request = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ expect(data.ext.marketplace).to.equal(undefined);
+ });
+
+ it('should be pubmatic and groupm when allowedAlternateBidderCodes is \'groupm\'', function () {
+ bidderSettingStub.withArgs('pubmatic', 'allowAlternateBidderCodes').returns(true);
+ bidderSettingStub.withArgs('pubmatic', 'allowedAlternateBidderCodes').returns(['groupm']);
+ let request = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id',
+ bidderCode: 'pubmatic'
+ });
+ let data = JSON.parse(request.data);
+ expect(data.ext.marketplace.allowedbidders).to.be.an('array');
+ expect(data.ext.marketplace.allowedbidders.length).to.equal(2);
+ expect(data.ext.marketplace.allowedbidders[0]).to.equal('pubmatic');
+ expect(data.ext.marketplace.allowedbidders[1]).to.equal('groupm');
+ });
+
+ it('should be ALL by default', function () {
+ bidderSettingStub.returns(true);
+ let request = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id'
+ });
+ let data = JSON.parse(request.data);
+ expect(data.ext.marketplace.allowedbidders).to.be.an('array');
+ expect(data.ext.marketplace.allowedbidders[0]).to.equal('all');
+ });
+
+ it('should be ALL when allowedAlternateBidderCodes is \'*\'', function () {
+ bidderSettingStub.withArgs('pubmatic', 'allowAlternateBidderCodes').returns(true);
+ bidderSettingStub.withArgs('pubmatic', 'allowedAlternateBidderCodes').returns(['*']);
+ let request = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id',
+ bidderCode: 'pubmatic'
+ });
+ let data = JSON.parse(request.data);
+ expect(data.ext.marketplace.allowedbidders).to.be.an('array');
+ expect(data.ext.marketplace.allowedbidders[0]).to.equal('all');
+ });
+ })
+
it('Set content from config, set site.content', function() {
let sandbox = sinon.sandbox.create();
const content = {
@@ -1141,7 +1214,7 @@ describe('PubMatic adapter', function () {
expect(data.device.dnt).to.equal((navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0);
expect(data.device.h).to.equal(screen.height);
expect(data.device.w).to.equal(screen.width);
- expect(data.device.language).to.equal(navigator.language);
+ expect(data.device.language).to.equal(navigator.language.split('-')[0]);
expect(data.device.newkey).to.equal('new-device-data');// additional data from config
sandbox.restore();
});
@@ -1631,44 +1704,79 @@ describe('PubMatic adapter', function () {
describe('FPD', function() {
let newRequest;
- it('ortb2.site should be merged in the request', function() {
- let sandbox = sinon.sandbox.create();
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- 'ortb2': {
- site: {
- domain: 'page.example.com',
- cat: ['IAB2'],
- sectioncat: ['IAB2-2']
- }
+ describe('ortb2.site should not override page, domain & ref values', function() {
+ it('When above properties are present in ortb2.site', function() {
+ const ortb2 = {
+ site: {
+ domain: 'page.example.com',
+ page: 'https://page.example.com/here.html',
+ ref: 'https://page.example.com/here.html'
}
};
- return config[key];
+ const request = spec.buildRequests(bidRequests, {ortb2});
+ let data = JSON.parse(request.data);
+ expect(data.site.domain).not.equal('page.example.com');
+ expect(data.site.page).not.equal('https://page.example.com/here.html');
+ expect(data.site.ref).not.equal('https://page.example.com/here.html');
+ });
+
+ it('When above properties are absent in ortb2.site', function () {
+ const ortb2 = {
+ site: {}
+ };
+ let request = spec.buildRequests(bidRequests, {
+ auctionId: 'new-auction-id',
+ ortb2
+ });
+ let data = JSON.parse(request.data);
+ let response = spec.interpretResponse(bidResponses, request);
+ expect(data.site.page).to.equal(bidRequests[0].params.kadpageurl);
+ expect(data.site.domain).to.equal(_getDomainFromURL(data.site.page));
+ expect(response[0].referrer).to.equal(data.site.ref);
+ });
+
+ it('With some extra properties in ortb2.site', function() {
+ const ortb2 = {
+ site: {
+ domain: 'page.example.com',
+ page: 'https://page.example.com/here.html',
+ ref: 'https://page.example.com/here.html',
+ cat: ['IAB2'],
+ sectioncat: ['IAB2-2']
+ }
+ };
+ const request = spec.buildRequests(bidRequests, {ortb2});
+ let data = JSON.parse(request.data);
+ expect(data.site.domain).not.equal('page.example.com');
+ expect(data.site.page).not.equal('https://page.example.com/here.html');
+ expect(data.site.ref).not.equal('https://page.example.com/here.html');
+ expect(data.site.cat).to.deep.equal(['IAB2']);
+ expect(data.site.sectioncat).to.deep.equal(['IAB2-2']);
});
- const request = spec.buildRequests(bidRequests, {});
+ });
+
+ it('ortb2.site should be merged except page, domain & ref in the request', function() {
+ const ortb2 = {
+ site: {
+ cat: ['IAB2'],
+ sectioncat: ['IAB2-2']
+ }
+ };
+ const request = spec.buildRequests(bidRequests, {ortb2});
let data = JSON.parse(request.data);
- expect(data.site.domain).to.equal('page.example.com');
expect(data.site.cat).to.deep.equal(['IAB2']);
expect(data.site.sectioncat).to.deep.equal(['IAB2-2']);
- sandbox.restore();
});
it('ortb2.user should be merged in the request', function() {
- let sandbox = sinon.sandbox.create();
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- 'ortb2': {
- user: {
- yob: 1985
- }
- }
- };
- return config[key];
- });
- const request = spec.buildRequests(bidRequests, {});
+ const ortb2 = {
+ user: {
+ yob: 1985
+ }
+ };
+ const request = spec.buildRequests(bidRequests, {ortb2});
let data = JSON.parse(request.data);
expect(data.user.yob).to.equal(1985);
- sandbox.restore();
});
describe('ortb2Imp', function() {
@@ -2389,68 +2497,6 @@ describe('PubMatic adapter', function () {
expect(data.user.eids).to.equal(undefined);
});
});
-
- describe('FlocId', function() {
- it('send the FlocId if it is present', function() {
- bidRequests[0].userId = {};
- bidRequests[0].userId.flocId = {
- id: '1234',
- version: 'chrome1.1'
- }
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'chrome.com',
- 'uids': [{
- 'id': '1234',
- 'atype': 1,
- 'ext': {
- 'ver': 'chrome1.1'
- }
- }]
- }]);
- expect(data.user.data).to.deep.equal([{
- id: 'FLOC',
- name: 'FLOC',
- ext: {
- ver: 'chrome1.1'
- },
- segment: [{
- id: '1234',
- name: 'chrome.com',
- value: '1234'
- }]
- }]);
- });
-
- it('appnend the flocId if userIds are present', function() {
- bidRequests[0].userId = {};
- bidRequests[0].userId.netId = 'netid-user-id';
- bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId);
- bidRequests[0].userId.flocId = {
- id: '1234',
- version: 'chrome1.1'
- }
- let request = spec.buildRequests(bidRequests, {});
- let data = JSON.parse(request.data);
- expect(data.user.eids).to.deep.equal([{
- 'source': 'netid.de',
- 'uids': [{
- 'id': 'netid-user-id',
- 'atype': 1
- }]
- }, {
- 'source': 'chrome.com',
- 'uids': [{
- 'id': '1234',
- 'atype': 1,
- 'ext': {
- 'ver': 'chrome1.1'
- }
- }]
- }]);
- });
- });
});
it('Request params check for video ad', function () {
@@ -3212,30 +3258,24 @@ describe('PubMatic adapter', function () {
expect(data.ext.acat).to.exist.and.to.deep.equal(['IAB1', 'IAB2', 'IAB3']);
});
it('ortb2.ext.prebid.bidderparams.pubmatic.acat should be passed in request payload', function() {
- let sandbox = sinon.sandbox.create();
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- 'ortb2': {
- ext: {
- prebid: {
- bidderparams: {
- pubmatic: {
- acat: ['IAB1', 'IAB2', 'IAB1', 'IAB2', 'IAB1', 'IAB2']
- }
- }
+ const ortb2 = {
+ ext: {
+ prebid: {
+ bidderparams: {
+ pubmatic: {
+ acat: ['IAB1', 'IAB2', 'IAB1', 'IAB2', 'IAB1', 'IAB2']
}
}
}
- };
- return config[key];
- });
+ }
+ };
const request = spec.buildRequests(bidRequests, {
auctionId: 'new-auction-id',
- bidderCode: 'pubmatic'
+ bidderCode: 'pubmatic',
+ ortb2
});
let data = JSON.parse(request.data);
expect(data.ext.acat).to.deep.equal(['IAB1', 'IAB2']);
- sandbox.restore();
});
});
@@ -3344,22 +3384,16 @@ describe('PubMatic adapter', function () {
it('ortb2.bcat should merged with slot level bcat param', function() {
multipleBidRequests[0].params.bcat = ['IAB-1', 'IAB-2'];
- let sandbox = sinon.sandbox.create();
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- 'ortb2': {
- bcat: ['IAB-3', 'IAB-4']
- }
- };
- return config[key];
- });
+ const ortb2 = {
+ bcat: ['IAB-3', 'IAB-4']
+ };
const request = spec.buildRequests(multipleBidRequests, {
auctionId: 'new-auction-id',
- bidderCode: 'pubmatic'
+ bidderCode: 'pubmatic',
+ ortb2
});
let data = JSON.parse(request.data);
expect(data.bcat).to.deep.equal(['IAB-1', 'IAB-2', 'IAB-3', 'IAB-4']);
- sandbox.restore();
});
});
diff --git a/test/spec/modules/pubperfAnalyticsAdapter_spec.js b/test/spec/modules/pubperfAnalyticsAdapter_spec.js
index b316b44617a..160529125d3 100644
--- a/test/spec/modules/pubperfAnalyticsAdapter_spec.js
+++ b/test/spec/modules/pubperfAnalyticsAdapter_spec.js
@@ -49,7 +49,8 @@ describe('Pubperf Analytics Adapter', function() {
events.emit(constants.EVENTS.AUCTION_END, {});
events.emit(constants.EVENTS.BID_TIMEOUT, {});
- sinon.assert.callCount(pubperfAnalytics.track, 6);
+ // 6 Pubperf events + 1 Clean.io event
+ sinon.assert.callCount(pubperfAnalytics.track, 7);
});
});
});
diff --git a/test/spec/modules/pubstackAnalyticsAdapter_spec.js b/test/spec/modules/pubstackAnalyticsAdapter_spec.js
index 4df25f1665b..3d01a0bb506 100644
--- a/test/spec/modules/pubstackAnalyticsAdapter_spec.js
+++ b/test/spec/modules/pubstackAnalyticsAdapter_spec.js
@@ -33,6 +33,7 @@ describe('Pubstack Analytics Adapter', () => {
events.emit(constants.EVENTS.NO_BID, args)
// Then
- expect(queue.length).to.eql(6);
+ // 6 Pubstack events + 1 Clean.io event
+ expect(queue.length).to.eql(7);
});
});
diff --git a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js
index 3be4ea3d69c..dd5c223b767 100644
--- a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js
+++ b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js
@@ -71,10 +71,10 @@ describe('PubWise Prebid Analytics', function () {
events.emit(constants.EVENTS.AUCTION_END, {});
// eslint-disable-next-line
- //console.log(requests);
+ //console.log(requests);
/* testing for 6 calls, including the 2 we're not currently tracking */
- sandbox.assert.callCount(pubwiseAnalytics.track, 7);
+ sandbox.assert.callCount(pubwiseAnalytics.track, 8);
});
it('should initialize the auction properly', function () {
@@ -92,7 +92,7 @@ describe('PubWise Prebid Analytics', function () {
let request = requests[0];
let data = JSON.parse(request.requestBody);
// eslint-disable-next-line
- // console.log(data.metaData);
+ // console.log(data.metaData);
expect(data.metaData, 'metaData property').to.exist;
expect(data.metaData.pbjs_version, 'pbjs version').to.equal('$prebid.version$')
expect(data.metaData.session_id, 'session id').not.to.be.empty
diff --git a/test/spec/modules/pubwiseBidAdapter_spec.js b/test/spec/modules/pubwiseBidAdapter_spec.js
index 450b028f6c7..1cf7a7dd280 100644
--- a/test/spec/modules/pubwiseBidAdapter_spec.js
+++ b/test/spec/modules/pubwiseBidAdapter_spec.js
@@ -99,13 +99,15 @@ const sampleValidBannerBidRequest = {
'crumbs': {
'pubcid': '9a62f261-3c0b-4cc8-8db3-a72ae86ec6ba'
},
- 'fpd': {
- 'context': {
- 'adServer': {
- 'name': 'gam',
- 'adSlot': '/19968336/header-bid-tag-0'
- },
- 'pbAdSlot': '/19968336/header-bid-tag-0'
+ ortb2Imp: {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam',
+ adslot: '/19968336/header-bid-tag-0'
+ },
+ pbadslot: '/19968336/header-bid-tag-0',
+ }
}
},
'mediaTypes': {
@@ -175,13 +177,15 @@ const sampleValidBidRequests = [
'required': false
}
},
- 'fpd': {
- 'context': {
- 'adServer': {
- 'name': 'gam',
- 'adSlot': '/19968336/header-bid-tag-0'
- },
- 'pbAdSlot': '/19968336/header-bid-tag-0'
+ ortb2Imp: {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam',
+ adslot: '/19968336/header-bid-tag-0'
+ },
+ pbadslot: '/19968336/header-bid-tag-0',
+ }
}
},
'mediaTypes': {
@@ -246,13 +250,15 @@ const sampleBidderBannerRequest = {
'crumbs': {
'pubcid': '9a62f261-3c0b-4cc8-8db3-a72ae86ec6ba'
},
- 'fpd': {
- 'context': {
- 'adServer': {
- 'name': 'gam',
- 'adSlot': '/19968336/header-bid-tag-0'
- },
- 'pbAdSlot': '/19968336/header-bid-tag-0'
+ ortb2Imp: {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam',
+ adslot: '/19968336/header-bid-tag-0'
+ },
+ pbadslot: '/19968336/header-bid-tag-0',
+ }
}
},
'mediaTypes': {
@@ -327,13 +333,15 @@ const sampleBidderRequest = {
'required': false
}
},
- 'fpd': {
- 'context': {
- 'adServer': {
- 'name': 'gam',
- 'adSlot': '/19968336/header-bid-tag-0'
- },
- 'pbAdSlot': '/19968336/header-bid-tag-0'
+ ortb2Imp: {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam',
+ adslot: '/19968336/header-bid-tag-0'
+ },
+ pbadslot: '/19968336/header-bid-tag-0',
+ }
}
},
'mediaTypes': {
diff --git a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js b/test/spec/modules/pubxaiAnalyticsAdapter_spec.js
index 63364b867be..1ad23b9a41e 100644
--- a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js
+++ b/test/spec/modules/pubxaiAnalyticsAdapter_spec.js
@@ -624,6 +624,11 @@ describe('pubxai analytics adapter', function() {
}
},
'floorProvider': 'PubXFloorProvider',
+ 'floorFetchStatus': 'success',
+ 'floorLocation': 'fetch',
+ 'floorModelVersion': 'test model 1.0',
+ 'floorSkipRate': 0,
+ 'isFloorSkipped': false,
'isWinningBid': true,
'mediaType': 'banner',
'netRevenue': true,
diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js
index c8ec0493d54..4426c91e1ec 100644
--- a/test/spec/modules/pulsepointBidAdapter_spec.js
+++ b/test/spec/modules/pulsepointBidAdapter_spec.js
@@ -195,7 +195,8 @@ describe('PulsePoint Adapter Tests', function () {
const bidderRequest = {
refererInfo: {
- referer: 'https://publisher.com/home'
+ page: 'https://publisher.com/home',
+ ref: 'https://referrer'
}
};
@@ -208,7 +209,7 @@ describe('PulsePoint Adapter Tests', function () {
expect(ortbRequest.site).to.not.equal(null);
expect(ortbRequest.site.publisher).to.not.equal(null);
expect(ortbRequest.site.publisher.id).to.equal('p10000');
- expect(ortbRequest.site.ref).to.equal(window.top.document.referrer);
+ expect(ortbRequest.site.ref).to.equal(bidderRequest.refererInfo.ref);
expect(ortbRequest.site.page).to.equal('https://publisher.com/home');
expect(ortbRequest.imp).to.have.lengthOf(2);
// device object
diff --git a/test/spec/modules/pxyzBidAdapter_spec.js b/test/spec/modules/pxyzBidAdapter_spec.js
index 21dd252c909..3a336c86e46 100644
--- a/test/spec/modules/pxyzBidAdapter_spec.js
+++ b/test/spec/modules/pxyzBidAdapter_spec.js
@@ -8,7 +8,7 @@ const GDPR_CONSENT = 'XYZ-CONSENT';
const BIDDER_REQUEST = {
refererInfo: {
- referer: 'https://example.com'
+ page: 'https://example.com',
}
};
diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js
index 5e0d129581c..d10fea829bc 100644
--- a/test/spec/modules/quantcastBidAdapter_spec.js
+++ b/test/spec/modules/quantcastBidAdapter_spec.js
@@ -19,7 +19,15 @@ describe('Quantcast adapter', function () {
let bidRequest;
let bidderRequest;
+ afterEach(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
+ });
beforeEach(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ quantcast: {
+ storageAllowed: true
+ }
+ };
bidRequest = {
bidder: 'quantcast',
bidId: '2f7b179d443f14',
@@ -39,8 +47,9 @@ describe('Quantcast adapter', function () {
bidderRequest = {
refererInfo: {
- referer: 'http://example.com/hello.html',
- canonicalUrl: 'http://example.com/hello.html'
+ page: 'http://example.com/hello.html',
+ ref: 'http://example.com/hello.html',
+ domain: 'example.com'
}
};
@@ -438,74 +447,6 @@ describe('Quantcast adapter', function () {
expect(parsed.gdprConsent).to.equal('consentString');
});
- it('allows TCF v1 request with consent for purpose 1', function () {
- const bidderRequest = {
- gdprConsent: {
- gdprApplies: true,
- consentString: 'consentString',
- vendorData: {
- vendorConsents: {
- '11': true
- },
- purposeConsents: {
- '1': true
- }
- },
- apiVersion: 1
- }
- };
-
- const requests = qcSpec.buildRequests([bidRequest], bidderRequest);
- const parsed = JSON.parse(requests[0].data);
-
- expect(parsed.gdprSignal).to.equal(1);
- expect(parsed.gdprConsent).to.equal('consentString');
- });
-
- it('blocks TCF v1 request without vendor consent', function () {
- const bidderRequest = {
- gdprConsent: {
- gdprApplies: true,
- consentString: 'consentString',
- vendorData: {
- vendorConsents: {
- '11': false
- },
- purposeConsents: {
- '1': true
- }
- },
- apiVersion: 1
- }
- };
-
- const requests = qcSpec.buildRequests([bidRequest], bidderRequest);
-
- expect(requests).to.equal(undefined);
- });
-
- it('blocks TCF v1 request without consent for purpose 1', function () {
- const bidderRequest = {
- gdprConsent: {
- gdprApplies: true,
- consentString: 'consentString',
- vendorData: {
- vendorConsents: {
- '11': true
- },
- purposeConsents: {
- '1': false
- }
- },
- apiVersion: 1
- }
- };
-
- const requests = qcSpec.buildRequests([bidRequest], bidderRequest);
-
- expect(requests).to.equal(undefined);
- });
-
it('allows TCF v2 request when Quantcast has consent for purpose 1', function() {
const bidderRequest = {
gdprConsent: {
diff --git a/test/spec/modules/qwarryBidAdapter_spec.js b/test/spec/modules/qwarryBidAdapter_spec.js
index 560206681ee..5d48d92066a 100644
--- a/test/spec/modules/qwarryBidAdapter_spec.js
+++ b/test/spec/modules/qwarryBidAdapter_spec.js
@@ -89,7 +89,7 @@ describe('qwarryBidAdapter', function () {
consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='
},
refererInfo: {
- referer: 'http://test.com/path.html'
+ page: 'http://test.com/path.html',
}
})
diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js
index 271f7cb1147..3ad7ada2ae7 100644
--- a/test/spec/modules/radsBidAdapter_spec.js
+++ b/test/spec/modules/radsBidAdapter_spec.js
@@ -105,13 +105,13 @@ describe('radsAdapter', function () {
// Without gdprConsent
let bidderRequest = {
refererInfo: {
- referer: 'some_referrer.net'
+ page: 'some_referrer.net'
}
}
// With gdprConsent
var bidderRequestGdprConsent = {
refererInfo: {
- referer: 'some_referrer.net'
+ page: 'some_referrer.net'
},
gdprConsent: {
consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
diff --git a/test/spec/modules/rasBidAdapter_spec.js b/test/spec/modules/rasBidAdapter_spec.js
new file mode 100644
index 00000000000..8c378aaa416
--- /dev/null
+++ b/test/spec/modules/rasBidAdapter_spec.js
@@ -0,0 +1,192 @@
+import { expect } from 'chai';
+import { spec } from 'modules/rasBidAdapter.js';
+import { newBidder } from 'src/adapters/bidderFactory.js';
+
+const CSR_ENDPOINT = 'https://csr.onet.pl/4178463/csr-006/csr.json?nid=4178463&';
+
+describe('rasBidAdapter', function () {
+ const adapter = newBidder(spec);
+
+ describe('inherited functions', function () {
+ it('exists and is a function', function () {
+ expect(adapter.callBids).to.exist.and.to.be.a('function');
+ });
+ });
+
+ describe('isBidRequestValid', function () {
+ it('should return true when required params found', function () {
+ const bid = {
+ sizes: [[300, 250], [300, 600]],
+ bidder: 'ras',
+ params: {
+ slot: 'slot',
+ area: 'areatest',
+ site: 'test',
+ network: '4178463'
+ }
+ };
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+ });
+
+ it('should return false when required params not found', function () {
+ const failBid = {
+ sizes: [[300, 250], [300, 300]],
+ bidder: 'ras',
+ params: {
+ site: 'test',
+ network: '4178463'
+ }
+ };
+ expect(spec.isBidRequestValid(failBid)).to.equal(false);
+ });
+
+ it('should return nothing when bid request is malformed', function () {
+ const failBid = {
+ sizes: [[300, 250], [300, 300]],
+ bidder: 'ras',
+ };
+ expect(spec.isBidRequestValid(failBid)).to.equal(undefined);
+ });
+ });
+
+ describe('buildRequests', function () {
+ const bid = {
+ sizes: [[300, 250], [300, 600]],
+ bidder: 'ras',
+ bidId: 1,
+ params: {
+ slot: 'test',
+ area: 'areatest',
+ site: 'test',
+ slotSequence: '0',
+ network: '4178463'
+ }
+ };
+ const bid2 = {
+ sizes: [[750, 300]],
+ bidder: 'ras',
+ bidId: 2,
+ params: {
+ slot: 'test2',
+ area: 'areatest',
+ site: 'test',
+ network: '4178463'
+ }
+ };
+
+ it('should parse bids to request', function () {
+ const requests = spec.buildRequests([bid], {
+ 'gdprConsent': {
+ 'gdprApplies': true,
+ 'consentString': 'some-consent-string'
+ },
+ 'refererInfo': {
+ 'ref': 'https://example.org/',
+ 'page': 'https://example.com/'
+ }
+ });
+ expect(requests[0].url).to.have.string(CSR_ENDPOINT);
+ expect(requests[0].url).to.have.string('slot0=test');
+ expect(requests[0].url).to.have.string('id0=1');
+ expect(requests[0].url).to.have.string('site=test');
+ expect(requests[0].url).to.have.string('area=areatest');
+ expect(requests[0].url).to.have.string('cre_format=html');
+ expect(requests[0].url).to.have.string('systems=das');
+ expect(requests[0].url).to.have.string('ems_url=1');
+ expect(requests[0].url).to.have.string('bid_rate=1');
+ expect(requests[0].url).to.have.string('gdpr_applies=true');
+ expect(requests[0].url).to.have.string('euconsent=some-consent-string');
+ expect(requests[0].url).to.have.string('du=https%3A%2F%2Fexample.com%2F');
+ expect(requests[0].url).to.have.string('dr=https%3A%2F%2Fexample.org%2F');
+ });
+
+ it('should return empty consent string when undefined', function () {
+ const requests = spec.buildRequests([bid]);
+ const gdpr = requests[0].url.search('gdpr_applies');
+ const euconsent = requests[0].url.search('euconsent=');
+ expect(gdpr).to.equal(-1);
+ expect(euconsent).to.equal(-1);
+ });
+
+ it('should parse bids to request from pageContext', function () {
+ const bidCopy = { ...bid };
+ bidCopy.params = {
+ ...bid.params,
+ pageContext: {
+ dv: 'test/areatest',
+ du: 'https://example.com/',
+ dr: 'https://example.org/',
+ keyWords: ['val1', 'val2'],
+ keyValues: {
+ adunit: 'test/areatest'
+ }
+ }
+ };
+ const requests = spec.buildRequests([bidCopy, bid2]);
+ expect(requests[0].url).to.have.string(CSR_ENDPOINT);
+ expect(requests[0].url).to.have.string('slot0=test');
+ expect(requests[0].url).to.have.string('id0=1');
+ expect(requests[0].url).to.have.string('iusizes0=300x250%2C300x600');
+ expect(requests[0].url).to.have.string('slot1=test2');
+ expect(requests[0].url).to.have.string('id1=2');
+ expect(requests[0].url).to.have.string('iusizes1=750x300');
+ expect(requests[0].url).to.have.string('site=test');
+ expect(requests[0].url).to.have.string('area=areatest');
+ expect(requests[0].url).to.have.string('cre_format=html');
+ expect(requests[0].url).to.have.string('systems=das');
+ expect(requests[0].url).to.have.string('ems_url=1');
+ expect(requests[0].url).to.have.string('bid_rate=1');
+ expect(requests[0].url).to.have.string('du=https%3A%2F%2Fexample.com%2F');
+ expect(requests[0].url).to.have.string('dr=https%3A%2F%2Fexample.org%2F');
+ expect(requests[0].url).to.have.string('DV=test%2Fareatest');
+ expect(requests[0].url).to.have.string('kwrd=val1%2Bval2');
+ expect(requests[0].url).to.have.string('kvadunit=test%2Fareatest');
+ expect(requests[0].url).to.have.string('pos0=0');
+ });
+ });
+
+ describe('interpretResponse', function () {
+ const response = {
+ 'adsCheck': 'ok',
+ 'geoloc': {},
+ 'ir': '92effd60-0c84-4dac-817e-763ea7b8ac65',
+ 'ads': [
+ {
+ 'id': 'flat-belkagorna',
+ 'slot': 'flat-belkagorna',
+ 'prio': 10,
+ 'type': 'html',
+ 'bid_rate': 0.321123,
+ 'adid': 'das,50463,152276',
+ 'id_3': '12734',
+ 'html': ''
+ }
+ ],
+ 'iv': '202003191334467636346500'
+ };
+
+ it('should get correct bid response', function () {
+ const resp = spec.interpretResponse({ body: response }, { bidIds: [{ slot: 'flat-belkagorna', bidId: 1 }] });
+ expect(resp[0]).to.have.all.keys('cpm', 'currency', 'netRevenue', 'requestId', 'ttl', 'width', 'height', 'creativeId', 'dealId', 'ad', 'meta');
+ expect(resp.length).to.equal(1);
+ });
+
+ it('should handle empty ad', function () {
+ let res = {
+ 'ads': [{
+ type: 'empty'
+ }]
+ };
+ const resp = spec.interpretResponse({ body: res }, {});
+ expect(resp).to.deep.equal([]);
+ });
+
+ it('should handle empty server response', function () {
+ let res = {
+ 'ads': []
+ };
+ const resp = spec.interpretResponse({ body: res }, {});
+ expect(resp).to.deep.equal([]);
+ });
+ });
+});
diff --git a/test/spec/modules/readpeakBidAdapter_spec.js b/test/spec/modules/readpeakBidAdapter_spec.js
index 04358fad52b..8772aeac88f 100644
--- a/test/spec/modules/readpeakBidAdapter_spec.js
+++ b/test/spec/modules/readpeakBidAdapter_spec.js
@@ -16,7 +16,8 @@ describe('ReadPeakAdapter', function() {
beforeEach(function() {
bidderRequest = {
refererInfo: {
- referer: 'https://publisher.com/home'
+ page: 'https://publisher.com/home',
+ domain: 'publisher.com'
}
};
@@ -266,8 +267,8 @@ describe('ReadPeakAdapter', function() {
expect(data.imp[0].tagId).to.equal('test-tag-1');
expect(data.site.publisher.id).to.equal(nativeBidRequest.params.publisherId);
expect(data.site.id).to.equal(nativeBidRequest.params.siteId);
- expect(data.site.page).to.equal(bidderRequest.refererInfo.referer);
- expect(data.site.domain).to.equal(parseUrl(bidderRequest.refererInfo.referer).hostname);
+ expect(data.site.page).to.equal(bidderRequest.refererInfo.page);
+ expect(data.site.domain).to.equal(bidderRequest.refererInfo.domain);
expect(data.device).to.deep.contain({
ua: navigator.userAgent,
language: navigator.language
@@ -428,8 +429,8 @@ describe('ReadPeakAdapter', function() {
expect(data.imp[0].tagId).to.equal('test-tag-1');
expect(data.site.publisher.id).to.equal(bannerBidRequest.params.publisherId);
expect(data.site.id).to.equal(bannerBidRequest.params.siteId);
- expect(data.site.page).to.equal(bidderRequest.refererInfo.referer);
- expect(data.site.domain).to.equal(parseUrl(bidderRequest.refererInfo.referer).hostname);
+ expect(data.site.page).to.equal(bidderRequest.refererInfo.page);
+ expect(data.site.domain).to.equal(bidderRequest.refererInfo.domain);
expect(data.device).to.deep.contain({
ua: navigator.userAgent,
language: navigator.language
@@ -527,6 +528,7 @@ describe('ReadPeakAdapter', function() {
ad: bannerServerResponse.seatbid[0].bid[0].adm,
width: bannerServerResponse.seatbid[0].bid[0].w,
height: bannerServerResponse.seatbid[0].bid[0].h,
+ burl: bannerServerResponse.seatbid[0].bid[0].burl,
});
expect(bidResponse.meta).to.deep.equal({
advertiserDomains: ['readpeak.com'],
diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js
index f0d381ee3ed..6a6e79c633d 100644
--- a/test/spec/modules/relaidoBidAdapter_spec.js
+++ b/test/spec/modules/relaidoBidAdapter_spec.js
@@ -5,13 +5,8 @@ import { BANNER, VIDEO } from 'src/mediaTypes.js';
import { getStorageManager } from '../../../src/storageManager.js';
const UUID_KEY = 'relaido_uuid';
-const DEFAULT_USER_AGENT = window.navigator.userAgent;
-const MOBILE_USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Mobile/15E148 Safari/604.1';
const relaido_uuid = 'hogehoge';
-const setUADefault = () => { window.navigator.__defineGetter__('userAgent', function () { return DEFAULT_USER_AGENT }) };
-const setUAMobile = () => { window.navigator.__defineGetter__('userAgent', function () { return MOBILE_USER_AGENT }) };
-
const storage = getStorageManager();
storage.setCookie(UUID_KEY, relaido_uuid);
@@ -19,6 +14,7 @@ describe('RelaidoAdapter', function () {
let bidRequest;
let bidderRequest;
let serverResponse;
+ let serverResponseBanner;
let serverRequest;
let generateUUIDStub;
let triggerPixelStub;
@@ -51,7 +47,8 @@ describe('RelaidoAdapter', function () {
bidderRequest = {
timeout: 1000,
refererInfo: {
- referer: 'https://publisher.com/home'
+ page: 'https://publisher.com/home?aaa=test1&bbb=test2',
+ canonicalUrl: 'https://publisher.com/home'
}
};
serverResponse = {
@@ -76,14 +73,36 @@ describe('RelaidoAdapter', function () {
uuid: relaido_uuid,
}
};
+ serverResponseBanner = {
+ body: {
+ status: 'ok',
+ ads: [{
+ placementId: 100000,
+ width: 640,
+ height: 360,
+ bidId: '2ed93003f7bb99',
+ price: 500,
+ model: 'vcpm',
+ currency: 'JPY',
+ creativeId: 1000,
+ adTag: '%3Cdiv%3E%3Cimg%20src%3D%22https%3A%2F%2Frelaido%2Ftest.jpg%22%20%2F%3E%3C%2Fdiv%3E',
+ syncUrl: 'https://relaido/sync.html',
+ adomain: ['relaido.co.jp', 'www.cmertv.co.jp'],
+ mediaType: 'banner'
+ }],
+ syncUrl: 'https://api-dev.ulizaex.com/tr/v1/prebid/sync.html',
+ uuid: relaido_uuid,
+ }
+ };
serverRequest = {
method: 'POST',
data: {
bids: [{
bidId: bidRequest.bidId,
- width: bidRequest.mediaTypes.video.playerSize[0][0],
- height: bidRequest.mediaTypes.video.playerSize[0][1],
- mediaType: 'video'}]
+ width: bidRequest.mediaTypes.video.playerSize[0][0] || bidRequest.mediaTypes.video.playerSize[0],
+ height: bidRequest.mediaTypes.video.playerSize[0][1] || bidRequest.mediaTypes.video.playerSize[1],
+ mediaType: 'video'
+ }]
}
};
});
@@ -98,8 +117,34 @@ describe('RelaidoAdapter', function () {
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
});
+ it('should return true when not existed mediaTypes.video.playerSize and existed valid params.video.playerSize by video', function () {
+ bidRequest.mediaTypes = {
+ video: {
+ context: 'outstream'
+ }
+ };
+ bidRequest.params = {
+ placementId: '100000',
+ video: {
+ playerSize: [
+ [640, 360]
+ ]
+ }
+ };
+ expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
+ });
+
+ it('should return even true when the playerSize is Array[Number, Number] by video', function () {
+ bidRequest.mediaTypes = {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 360]
+ }
+ };
+ expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
+ });
+
it('should return true when the required params are passed by banner', function () {
- setUAMobile();
bidRequest.mediaTypes = {
banner: {
sizes: [
@@ -108,11 +153,9 @@ describe('RelaidoAdapter', function () {
}
};
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- setUADefault();
});
it('should return false when missing 300x250 over and 1x1 by banner', function () {
- setUAMobile();
bidRequest.mediaTypes = {
banner: {
sizes: [
@@ -122,11 +165,9 @@ describe('RelaidoAdapter', function () {
}
};
expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- setUADefault();
});
it('should return true when 300x250 by banner', function () {
- setUAMobile();
bidRequest.mediaTypes = {
banner: {
sizes: [
@@ -135,11 +176,9 @@ describe('RelaidoAdapter', function () {
}
};
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- setUADefault();
});
it('should return true when 1x1 by banner', function () {
- setUAMobile();
bidRequest.mediaTypes = {
banner: {
sizes: [
@@ -148,11 +187,9 @@ describe('RelaidoAdapter', function () {
}
};
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- setUADefault();
});
it('should return true when 300x250 over by banner', function () {
- setUAMobile();
bidRequest.mediaTypes = {
banner: {
sizes: [
@@ -162,7 +199,6 @@ describe('RelaidoAdapter', function () {
}
};
expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
- setUADefault();
});
it('should return false when the placementId params are missing', function () {
@@ -178,23 +214,10 @@ describe('RelaidoAdapter', function () {
});
it('should return false when the mediaType banner params are missing', function () {
- setUAMobile();
bidRequest.mediaTypes = {
banner: {}
};
expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
- setUADefault();
- });
-
- it('should return false when the non-mobile', function () {
- bidRequest.mediaTypes = {
- banner: {
- sizes: [
- [300, 250]
- ]
- }
- };
- expect(spec.isBidRequestValid(bidRequest)).to.equal(false);
});
it('should return false when the mediaTypes params are missing', function () {
@@ -211,7 +234,8 @@ describe('RelaidoAdapter', function () {
const request = data.bids[0];
expect(bidRequests.method).to.equal('POST');
expect(bidRequests.url).to.equal('https://api.relaido.jp/bid/v1/sprebid');
- expect(data.ref).to.equal(bidderRequest.refererInfo.referer);
+ expect(data.canonical_url_hash).to.equal('e6092f44a0044903ae3764126eedd6187c1d9f04');
+ expect(data.ref).to.equal(bidderRequest.refererInfo.page);
expect(data.timeout_ms).to.equal(bidderRequest.timeout);
expect(request.ad_unit_code).to.equal(bidRequest.adUnitCode);
expect(request.auction_id).to.equal(bidRequest.auctionId);
@@ -226,7 +250,6 @@ describe('RelaidoAdapter', function () {
});
it('should build bid requests by banner', function () {
- setUAMobile();
bidRequest.mediaTypes = {
video: {
context: 'outstream',
@@ -246,10 +269,10 @@ describe('RelaidoAdapter', function () {
expect(data.bids).to.have.lengthOf(1);
const request = data.bids[0];
expect(request.media_type).to.equal('banner');
+ expect(request.banner_sizes).to.equal('640x360,1x1');
});
it('should take 1x1 size', function () {
- setUAMobile();
bidRequest.mediaTypes = {
video: {
context: 'outstream',
@@ -292,7 +315,7 @@ describe('RelaidoAdapter', function () {
});
describe('spec.interpretResponse', function () {
- it('should build bid response by video', function () {
+ it('should build bid response by video and serverResponse contains vast', function () {
const bidResponses = spec.interpretResponse(serverResponse, serverRequest);
expect(bidResponses).to.have.lengthOf(1);
const response = bidResponses[0];
@@ -309,7 +332,7 @@ describe('RelaidoAdapter', function () {
expect(response.ad).to.be.undefined;
});
- it('should build bid response by banner', function () {
+ it('should build bid response by banner and serverResponse contains vast', function () {
serverResponse.body.ads[0].mediaType = 'banner';
const bidResponses = spec.interpretResponse(serverResponse, serverRequest);
expect(bidResponses).to.have.lengthOf(1);
@@ -327,6 +350,19 @@ describe('RelaidoAdapter', function () {
expect(response.ad).to.include(`window.RelaidoPlayer.renderAd`);
});
+ it('should build bid response by banner and serverResponse contains adTag', function () {
+ const bidResponses = spec.interpretResponse(serverResponseBanner, serverRequest);
+ expect(bidResponses).to.have.lengthOf(1);
+ const response = bidResponses[0];
+ expect(response.requestId).to.equal(serverRequest.data.bids[0].bidId);
+ expect(response.cpm).to.equal(serverResponseBanner.body.ads[0].price);
+ expect(response.currency).to.equal(serverResponseBanner.body.ads[0].currency);
+ expect(response.creativeId).to.equal(serverResponseBanner.body.ads[0].creativeId);
+ expect(response.vastXml).to.be.undefined;
+ expect(response.playerUrl).to.be.undefined;
+ expect(response.ad).to.include(`

`);
+ });
+
it('should build bid response by video and playerUrl in ads', function () {
serverResponse.body.ads[0].playerUrl = 'https://relaido/player-customized.js';
const bidResponses = spec.interpretResponse(serverResponse, serverRequest);
diff --git a/test/spec/modules/revcontentBidAdapter_spec.js b/test/spec/modules/revcontentBidAdapter_spec.js
index 022dd0e1aa9..e6ef4adec87 100644
--- a/test/spec/modules/revcontentBidAdapter_spec.js
+++ b/test/spec/modules/revcontentBidAdapter_spec.js
@@ -45,7 +45,7 @@ describe('revcontent adapter', function () {
endpoint: 'trends-s0.revcontent.com'
}
}];
- let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}});
+ let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}});
request = request[0];
assert.equal(request.method, 'POST');
assert.equal(request.url, 'https://trends-s0.revcontent.com/rtb?apiKey=8a33fa9cf220ae685dcc3544f847cdda858d3b1c&userId=673&widgetId=33861');
@@ -66,7 +66,7 @@ describe('revcontent adapter', function () {
endpoint: 'trends-s0.revcontent.com'
}
}];
- let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}});
+ let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}});
request = request[0];
let data = Object.keys(request);
@@ -87,7 +87,7 @@ describe('revcontent adapter', function () {
bidfloor: 0.05
}
}];
- let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}});
+ let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}});
request = JSON.parse(request[0].data);
assert.equal(request.imp[0].bidfloor, 0.05);
assert.equal(request.device.ua, navigator.userAgent);
@@ -112,7 +112,7 @@ describe('revcontent adapter', function () {
currency: 'USD'
};
};
- let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}});
+ let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}});
request = JSON.parse(request[0].data);
assert.equal(request.imp[0].bidfloor, 0.07);
assert.equal(request.device.ua, navigator.userAgent);
@@ -146,7 +146,7 @@ describe('revcontent adapter', function () {
endpoint: 'trends-s0.revcontent.com'
}
}];
- let refererInfo = {referer: 'page'};
+ let refererInfo = {page: 'page'};
let request = spec.buildRequests(validBidRequests, {refererInfo});
request = JSON.parse(request[0].data);
diff --git a/test/spec/modules/rhythmoneBidAdapter_spec.js b/test/spec/modules/rhythmoneBidAdapter_spec.js
index e0e58fc89cd..359b02db37e 100644
--- a/test/spec/modules/rhythmoneBidAdapter_spec.js
+++ b/test/spec/modules/rhythmoneBidAdapter_spec.js
@@ -8,7 +8,7 @@ describe('rhythmone adapter tests', function () {
beforeEach(function() {
this.defaultBidderRequest = {
'refererInfo': {
- 'referer': 'Reference Page',
+ 'ref': 'Reference Page',
'stack': [
'aodomain.dvl',
'page.dvl'
@@ -647,35 +647,6 @@ describe('rhythmone adapter tests', function () {
});
});
- it('should return empty site.domain and site.page when refererInfo.stack is empty', function() {
- this.defaultBidderRequest.refererInfo.stack = [];
- var bidRequestList = [
- {
- 'bidder': 'rhythmone',
- 'params': {
- 'placementId': 'myplacement',
- 'zone': 'myzone',
- 'path': 'mypath'
- },
- 'mediaType': 'banner',
- 'adUnitCode': 'div-gpt-ad-1438287399331-0',
- 'sizes': [[300, 250]],
- 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec',
- 'bidderRequestId': '418b37f85e772c',
- 'auctionId': '18fd8b8b0bd757',
- 'bidRequestsCount': 1,
- 'bidId': '51ef8751f9aead'
- }
- ];
-
- var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest);
- const openrtbRequest = JSON.parse(bidRequest.data);
-
- expect(openrtbRequest.site.domain).to.equal('');
- expect(openrtbRequest.site.page).to.equal('');
- expect(openrtbRequest.site.ref).to.equal('Reference Page');
- });
-
it('should secure correctly', function() {
this.defaultBidderRequest.refererInfo.stack[0] = ['https://securesite.dvl'];
var bidRequestList = [
diff --git a/test/spec/modules/richaudienceBidAdapter_spec.js b/test/spec/modules/richaudienceBidAdapter_spec.js
index 9e9366072be..86d3df8be59 100644
--- a/test/spec/modules/richaudienceBidAdapter_spec.js
+++ b/test/spec/modules/richaudienceBidAdapter_spec.js
@@ -176,7 +176,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'http://domain.com',
+ page: 'http://domain.com',
numIframes: 0
}
}
@@ -205,7 +205,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -246,7 +246,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -265,7 +265,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -296,7 +296,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -311,7 +311,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -334,7 +334,7 @@ describe('Richaudience adapter tests', function () {
consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA'
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -583,7 +583,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -611,7 +611,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -640,7 +640,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
@@ -669,7 +669,7 @@ describe('Richaudience adapter tests', function () {
gdprApplies: true
},
refererInfo: {
- referer: 'https://domain.com',
+ page: 'https://domain.com',
numIframes: 0
}
});
diff --git a/test/spec/modules/riseBidAdapter_spec.js b/test/spec/modules/riseBidAdapter_spec.js
index 596c4d0f58c..7daedb9015a 100644
--- a/test/spec/modules/riseBidAdapter_spec.js
+++ b/test/spec/modules/riseBidAdapter_spec.js
@@ -7,6 +7,9 @@ import * as utils from 'src/utils.js';
const ENDPOINT = 'https://hb.yellowblue.io/hb-multi';
const TEST_ENDPOINT = 'https://hb.yellowblue.io/hb-multi-test';
+const RTB_DOMAIN_TEST = 'testseller.com';
+const RTB_DOMAIN_ENDPOINT = `https://${RTB_DOMAIN_TEST}/hb-multi`;
+const RTB_DOMAIN_TEST_ENDPOINT = `https://${RTB_DOMAIN_TEST}/hb-multi-test`;
const TTL = 360;
/* eslint no-console: ["error", { allow: ["log", "warn", "error"] }] */
@@ -53,6 +56,7 @@ describe('riseAdapter', function () {
'org': 'jdye8weeyirk00000001'
},
'bidId': '299ffc8cca0b87',
+ 'loop': 1,
'bidderRequestId': '1144f487e563f9',
'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d',
'mediaTypes': {
@@ -71,6 +75,7 @@ describe('riseAdapter', function () {
'org': 'jdye8weeyirk00000001'
},
'bidId': '299ffc8cca0b87',
+ 'loop': 1,
'bidderRequestId': '1144f487e563f9',
'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d',
'mediaTypes': {
@@ -91,6 +96,7 @@ describe('riseAdapter', function () {
'testMode': true
},
'bidId': '299ffc8cca0b87',
+ 'loop': 2,
'bidderRequestId': '1144f487e563f9',
'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d',
}
@@ -119,6 +125,20 @@ describe('riseAdapter', function () {
expect(request.method).to.equal('POST');
});
+ it('sends bid request to rtbDomain ENDPOINT via POST', function () {
+ bidRequests[0].params.rtbDomain = RTB_DOMAIN_TEST;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.url).to.equal(RTB_DOMAIN_ENDPOINT);
+ expect(request.method).to.equal('POST');
+ });
+
+ it('sends bid request to rtbDomain TEST ENDPOINT via POST', function () {
+ testModeBidRequests[0].params.rtbDomain = RTB_DOMAIN_TEST;
+ const request = spec.buildRequests(testModeBidRequests, bidderRequest);
+ expect(request.url).to.equal(RTB_DOMAIN_TEST_ENDPOINT);
+ expect(request.method).to.equal('POST');
+ });
+
it('should send the correct bid Id', function () {
const request = spec.buildRequests(bidRequests, bidderRequest);
expect(request.data.bids[0].bidId).to.equal('299ffc8cca0b87');
diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js
index 1f52e83dab9..bef3eda0afc 100644
--- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js
+++ b/test/spec/modules/rubiconAnalyticsAdapter_spec.js
@@ -235,7 +235,7 @@ const MOCK = {
],
'timeout': 3000,
'refererInfo': {
- 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
+ 'page': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
}
}
],
@@ -319,7 +319,7 @@ const MOCK = {
'timeout': 5000,
'start': 1519149562216,
'refererInfo': {
- 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
+ 'page': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html']
}
},
BID_RESPONSE: [
diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js
index 46b1b519a81..fb1b336ef92 100644
--- a/test/spec/modules/rubiconBidAdapter_spec.js
+++ b/test/spec/modules/rubiconBidAdapter_spec.js
@@ -248,7 +248,6 @@ describe('the rubicon adapter', function () {
criteoId: '1111',
};
bid.userIdAsEids = createEidsArray(bid.userId);
- bid.storedAuctionResponse = 11111;
}
function createVideoBidderRequestNoVideo() {
@@ -666,7 +665,7 @@ describe('the rubicon adapter', function () {
it('should add referer info to request data', function () {
let refererInfo = {
- referer: 'https://www.prebid.org',
+ page: 'https://www.prebid.org',
reachedTop: true,
numIframes: 1,
stack: [
@@ -683,29 +682,20 @@ describe('the rubicon adapter', function () {
expect(parseQuery(request.data).rf).to.equal('https://www.prebid.org');
});
- it('page_url should use params.referrer, config.getConfig("pageUrl"), bidderRequest.refererInfo in that order', function () {
+ it('page_url should use params.referrer, bidderRequest.refererInfo in that order', function () {
let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
expect(parseQuery(request.data).rf).to.equal('localhost');
delete bidderRequest.bids[0].params.referrer;
- let refererInfo = {referer: 'https://www.prebid.org'};
+ let refererInfo = {page: 'https://www.prebid.org'};
bidderRequest = Object.assign({refererInfo}, bidderRequest);
[request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
expect(parseQuery(request.data).rf).to.equal('https://www.prebid.org');
- let origGetConfig = config.getConfig;
- sandbox.stub(config, 'getConfig').callsFake(function (key) {
- if (key === 'pageUrl') {
- return 'https://www.rubiconproject.com';
- }
- return origGetConfig.apply(config, arguments);
- });
- [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
- expect(parseQuery(request.data).rf).to.equal('https://www.rubiconproject.com');
-
+ bidderRequest.refererInfo.page = 'http://www.prebid.org';
bidderRequest.bids[0].params.secure = true;
[request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
- expect(parseQuery(request.data).rf).to.equal('https://www.rubiconproject.com');
+ expect(parseQuery(request.data).rf).to.equal('https://www.prebid.org');
});
it('should use rubicon sizes if present (including non-mappable sizes)', function () {
@@ -927,15 +917,10 @@ describe('the rubicon adapter', function () {
}
};
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- ortb2: {
- site,
- user
- }
- };
- return utils.deepAccess(config, key);
- });
+ const ortb2 = {
+ site,
+ user
+ }
const expectedQuery = {
'kw': 'a,b,c,d',
@@ -953,7 +938,7 @@ describe('the rubicon adapter', function () {
};
// get the built request
- let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ let [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2})), bidderRequest);
let data = parseQuery(request.data);
// make sure that tg_v, tg_i, and kw values are correct
@@ -1630,6 +1615,47 @@ describe('the rubicon adapter', function () {
expect(post.ext.prebid.bidders.rubicon.integration).to.equal(PBS_INTEGRATION);
});
+ describe('ortb2imp sent to video bids', function () {
+ beforeEach(function () {
+ // initialize
+ if (bidderRequest.bids[0].hasOwnProperty('ortb2Imp')) {
+ delete bidderRequest.bids[0].ortb2Imp;
+ }
+ });
+
+ it('should add ortb values to video requests', function () {
+ createVideoBidderRequest();
+
+ sandbox.stub(Date, 'now').callsFake(() =>
+ bidderRequest.auctionStart + 100
+ );
+
+ bidderRequest.bids[0].ortb2Imp = {
+ ext: {
+ gpid: '/test/gpid',
+ data: {
+ pbadslot: '/test/pbadslot'
+ },
+ prebid: {
+ storedauctionresponse: {
+ id: 'sample_video_response'
+ }
+ }
+ }
+ }
+
+ let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ let post = request.data;
+
+ expect(post).to.have.property('imp');
+ // .with.length.of(1);
+ let imp = post.imp[0];
+ expect(imp.ext.gpid).to.equal('/test/gpid');
+ expect(imp.ext.data.pbadslot).to.equal('/test/pbadslot');
+ expect(imp.ext.prebid.storedauctionresponse.id).to.equal('sample_video_response');
+ });
+ });
+
it('should correctly set bidfloor on imp when getfloor in scope', function () {
createVideoBidderRequest();
// default getFloor response is empty object so should not break and not send hard_floor
@@ -2072,17 +2098,12 @@ describe('the rubicon adapter', function () {
data: [{foo: 'bar'}]
};
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- ortb2: {
- site,
- user
- }
- };
- return utils.deepAccess(config, key);
- });
+ const ortb2 = {
+ site,
+ user
+ };
- const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
+ const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2})), bidderRequest);
const expected = {
site: Object.assign({}, site, {keywords: bidderRequest.bids[0].params.keywords.join(',')}),
@@ -2100,28 +2121,38 @@ describe('the rubicon adapter', function () {
expect(request.data.user.ext.data).to.deep.equal(expected.userData);
});
- it('should include storedAuctionResponse in video bid request', function () {
+ it('should include pbadslot in bid request', function () {
createVideoBidderRequest();
+ bidderRequest.bids[0].ortb2Imp = {
+ ext: {
+ data: {
+ pbadslot: '1234567890'
+ }
+ }
+ }
sandbox.stub(Date, 'now').callsFake(() =>
bidderRequest.auctionStart + 100
);
const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
- expect(request.data.imp).to.exist.and.to.be.a('array');
- expect(request.data.imp).to.have.lengthOf(1);
- expect(request.data.imp[0].ext).to.exist.and.to.be.a('object');
- expect(request.data.imp[0].ext.prebid).to.exist.and.to.be.a('object');
- expect(request.data.imp[0].ext.prebid.storedauctionresponse).to.exist.and.to.be.a('object');
- expect(request.data.imp[0].ext.prebid.storedauctionresponse.id).to.equal('11111');
+ expect(request.data.imp[0].ext.data.pbadslot).to.equal('1234567890');
});
- it('should include pbadslot in bid request', function () {
+ it('should NOT include storedrequests in pbs payload', function () {
createVideoBidderRequest();
+ bidderRequest.bids[0].ortb2 = {
+ ext: {
+ prebid: {
+ storedrequest: 'no-send-top-level-sr'
+ }
+ }
+ }
+
bidderRequest.bids[0].ortb2Imp = {
ext: {
- data: {
- pbadslot: '1234567890'
+ prebid: {
+ storedrequest: 'no-send-imp-sr'
}
}
}
@@ -2131,7 +2162,8 @@ describe('the rubicon adapter', function () {
);
const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
- expect(request.data.imp[0].ext.data.pbadslot).to.equal('1234567890');
+ expect(request.data.ext.prebid.storedrequest).to.be.undefined;
+ expect(request.data.imp[0].ext.prebid.storedrequest).to.be.undefined;
});
it('should include GAM ad unit in bid request', function () {
diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js
index 1e0dca68d00..092fd3ebf9a 100644
--- a/test/spec/modules/seedtagBidAdapter_spec.js
+++ b/test/spec/modules/seedtagBidAdapter_spec.js
@@ -196,7 +196,7 @@ describe('Seedtag Adapter', function () {
describe('buildRequests method', function () {
const bidderRequest = {
- refererInfo: { referer: 'referer' },
+ refererInfo: { page: 'referer' },
timeout: 1000,
};
const mandatoryParams = {
@@ -223,6 +223,7 @@ describe('Seedtag Adapter', function () {
});
it('Common data request should be correct', function () {
+ const now = Date.now();
const request = spec.buildRequests(validBidRequests, bidderRequest);
const data = JSON.parse(request.data);
expect(data.url).to.equal('referer');
@@ -231,6 +232,9 @@ describe('Seedtag Adapter', function () {
expect(
['fixed', 'mobile', 'unknown'].indexOf(data.connectionType)
).to.be.above(-1);
+ expect(data.auctionStart).to.be.greaterThanOrEqual(now);
+ expect(data.ttfb).to.be.greaterThanOrEqual(0);
+
expect(data.bidRequests[0].adUnitCode).to.equal('adunit-code');
});
@@ -288,6 +292,31 @@ describe('Seedtag Adapter', function () {
it('should expose gvlid', function () {
expect(spec.gvlid).to.equal(157);
});
+ it('should handle uspConsent', function () {
+ const uspConsent = '1---';
+
+ bidderRequest['uspConsent'] = uspConsent;
+
+ const request = spec.buildRequests(validBidRequests, bidderRequest);
+ const payload = JSON.parse(request.data);
+
+ expect(payload.uspConsent).to.exist;
+ expect(payload.uspConsent).to.equal(uspConsent);
+ });
+
+ it("shouldn't send uspConsent when not available", function () {
+ const uspConsent = undefined;
+
+ bidderRequest['uspConsent'] = uspConsent;
+
+ const request = spec.buildRequests(
+ validBidRequests,
+ bidderRequest
+ );
+ const payload = JSON.parse(request.data);
+
+ expect(payload.uspConsent).to.not.exist;
+ });
});
});
diff --git a/test/spec/modules/shareUserIds_spec.js b/test/spec/modules/shareUserIds_spec.js
deleted file mode 100644
index 67e39533fc7..00000000000
--- a/test/spec/modules/shareUserIds_spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import {userIdTargeting} from '../../../modules/userIdTargeting.js';
-import { expect } from 'chai';
-
-describe('#userIdTargeting', function() {
- let userIds;
- let config;
-
- beforeEach(function() {
- userIds = {
- tdid: 'my-tdid'
- };
- config = {
- 'GAM': true,
- 'GAM_KEYS': {
- 'tdid': 'TD_ID'
- }
- };
- });
-
- it('Do nothing if config is invaild', function() {
- let pubads = window.googletag.pubads();
- pubads.clearTargeting();
- pubads.setTargeting('test', ['TEST']);
- userIdTargeting(userIds, JSON.stringify(config));
- expect(pubads.getTargeting('test')).to.deep.equal(['TEST']);
- });
-
- it('all UserIds are passed as is with GAM: true', function() {
- let pubads = window.googletag.pubads();
- pubads.clearTargeting();
- pubads.setTargeting('test', ['TEST']);
- delete config.GAM_KEYS;
- userIdTargeting(userIds, config);
- expect(pubads.getTargeting('test')).to.deep.equal(['TEST']);
- expect(pubads.getTargeting('tdid')).to.deep.equal(['my-tdid']);
- })
-
- it('Publisher prefered key-names are used', function() {
- let pubads = window.googletag.pubads();
- pubads.clearTargeting();
- pubads.setTargeting('test', ['TEST']);
- userIdTargeting(userIds, config);
- expect(pubads.getTargeting('test')).to.deep.equal(['TEST']);
- expect(pubads.getTargeting('TD_ID')).to.deep.equal(['my-tdid']);
- });
-
- it('Publisher does not want to pass an id', function() {
- let pubads = window.googletag.pubads();
- pubads.clearTargeting();
- pubads.setTargeting('test', ['TEST']);
- config.GAM_KEYS.tdid = '';
- userIdTargeting(userIds, config);
- expect(pubads.getTargeting('tdid')).to.be.an('array').that.is.empty;
- expect(pubads.getTargeting('test')).to.deep.equal(['TEST']);
- });
-
- it('User Id Targeting is added to googletag queue when GPT is not ready', function() {
- let pubads = window.googletag.pubads;
- delete window.googletag.pubads;
- userIdTargeting(userIds, config);
- window.googletag.pubads = pubads;
- window.googletag.cmd.map(command => command());
- expect(window.googletag.pubads().getTargeting('TD_ID')).to.deep.equal(['my-tdid']);
- });
-});
diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js
index 39238cc877f..bb5e8e69b6e 100644
--- a/test/spec/modules/sharethroughBidAdapter_spec.js
+++ b/test/spec/modules/sharethroughBidAdapter_spec.js
@@ -114,10 +114,6 @@ describe('sharethrough adapter spec', function () {
sharedid: {
id: 'fake-sharedid',
},
- flocId: {
- id: 'fake-flocid',
- version: '42',
- },
},
crumbs: {
pubcid: 'fake-pubcid-in-crumbs-obj',
@@ -170,7 +166,7 @@ describe('sharethrough adapter spec', function () {
bidderRequest = {
refererInfo: {
- referer: 'https://referer.com',
+ ref: 'https://referer.com',
},
};
});
@@ -222,7 +218,6 @@ describe('sharethrough adapter spec', function () {
'crwdcntrl.net': { id: 'fake-lotame' },
'parrable.com': { id: 'fake-parrable' },
'netid.de': { id: 'fake-netid' },
- 'chrome.com': { id: 'fake-flocid' },
};
expect(openRtbReq.user.ext.eids).to.be.an('array').that.have.length(Object.keys(expectedEids).length);
for (const eid of openRtbReq.user.ext.eids) {
@@ -485,21 +480,12 @@ describe('sharethrough adapter spec', function () {
},
},
},
+ bcat: ['IAB1', 'IAB2-1'],
+ badv: ['domain1.com', 'domain2.com'],
};
- let configStub;
-
- beforeEach(() => {
- configStub = sinon.stub(config, 'getConfig');
- configStub.withArgs('ortb2').returns(firstPartyData);
- });
-
- afterEach(() => {
- configStub.restore();
- });
-
it('should include first party data in open rtb request, site section', () => {
- const openRtbReq = spec.buildRequests(bidRequests, bidderRequest)[0].data;
+ const openRtbReq = spec.buildRequests(bidRequests, {...bidderRequest, ortb2: firstPartyData})[0].data;
expect(openRtbReq.site.name).to.equal(firstPartyData.site.name);
expect(openRtbReq.site.keywords).to.equal(firstPartyData.site.keywords);
@@ -509,13 +495,20 @@ describe('sharethrough adapter spec', function () {
});
it('should include first party data in open rtb request, user section', () => {
- const openRtbReq = spec.buildRequests(bidRequests, bidderRequest)[0].data;
+ const openRtbReq = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2: firstPartyData })[0].data;
expect(openRtbReq.user.yob).to.equal(firstPartyData.user.yob);
expect(openRtbReq.user.gender).to.equal(firstPartyData.user.gender);
expect(openRtbReq.user.ext.data).to.deep.equal(firstPartyData.user.ext.data);
expect(openRtbReq.user.ext.eids).not.to.be.undefined;
});
+
+ it('should include first party data in open rtb request, ORTB blocked section', () => {
+ const openRtbReq = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2: firstPartyData })[0].data;
+
+ expect(openRtbReq.bcat).to.deep.equal(firstPartyData.bcat);
+ expect(openRtbReq.badv).to.deep.equal(firstPartyData.badv);
+ });
});
});
@@ -617,11 +610,11 @@ describe('sharethrough adapter spec', function () {
const serverResponses = [{ body: { cookieSyncUrls: cookieSyncs } }];
it('returns an array of correctly formatted user syncs', function () {
- const syncArray = spec.getUserSyncs({ pixelEnabled: true }, serverResponses, null, 'fake-privacy-signal');
+ const syncArray = spec.getUserSyncs({ pixelEnabled: true }, serverResponses);
expect(syncArray).to.deep.equal([
- { type: 'image', url: 'cookieUrl1&us_privacy=fake-privacy-signal' },
- { type: 'image', url: 'cookieUrl2&us_privacy=fake-privacy-signal' },
- { type: 'image', url: 'cookieUrl3&us_privacy=fake-privacy-signal' }],
+ { type: 'image', url: 'cookieUrl1' },
+ { type: 'image', url: 'cookieUrl2' },
+ { type: 'image', url: 'cookieUrl3' }],
);
});
diff --git a/test/spec/modules/shinezBidAdapter_spec.js b/test/spec/modules/shinezBidAdapter_spec.js
new file mode 100644
index 00000000000..4e6c2d3420e
--- /dev/null
+++ b/test/spec/modules/shinezBidAdapter_spec.js
@@ -0,0 +1,479 @@
+import { expect } from 'chai';
+import { spec } from 'modules/shinezBidAdapter.js';
+import { newBidder } from 'src/adapters/bidderFactory.js';
+import { config } from 'src/config.js';
+import { BANNER, VIDEO } from '../../../src/mediaTypes.js';
+import * as utils from 'src/utils.js';
+
+const ENDPOINT = 'https://hb.sweetgum.io/hb-sz-multi';
+const TEST_ENDPOINT = 'https://hb.sweetgum.io/hb-multi-sz-test';
+const TTL = 360;
+/* eslint no-console: ["error", { allow: ["log", "warn", "error"] }] */
+
+describe('shinezAdapter', function () {
+ const adapter = newBidder(spec);
+
+ describe('inherited functions', function () {
+ it('exists and is a function', function () {
+ expect(adapter.callBids).to.exist.and.to.be.a('function');
+ });
+ });
+
+ describe('isBidRequestValid', function () {
+ const bid = {
+ 'bidder': spec.code,
+ 'adUnitCode': 'adunit-code',
+ 'sizes': [['640', '480']],
+ 'params': {
+ 'org': 'jdye8weeyirk00000001'
+ }
+ };
+
+ it('should return true when required params are passed', function () {
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
+ });
+
+ it('should return false when required params are not found', function () {
+ const newBid = Object.assign({}, bid);
+ delete newBid.params;
+ newBid.params = {
+ 'org': null
+ };
+ expect(spec.isBidRequestValid(newBid)).to.equal(false);
+ });
+ });
+
+ describe('buildRequests', function () {
+ const bidRequests = [
+ {
+ 'bidder': spec.code,
+ 'adUnitCode': 'adunit-code',
+ 'sizes': [[640, 480]],
+ 'params': {
+ 'org': 'jdye8weeyirk00000001'
+ },
+ 'bidId': '299ffc8cca0b87',
+ 'bidderRequestId': '1144f487e563f9',
+ 'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d',
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [[640, 480]],
+ 'context': 'instream'
+ }
+ },
+ 'vastXml': '"
..."'
+ },
+ {
+ 'bidder': spec.code,
+ 'adUnitCode': 'adunit-code',
+ 'sizes': [[300, 250]],
+ 'params': {
+ 'org': 'jdye8weeyirk00000001'
+ },
+ 'bidId': '299ffc8cca0b87',
+ 'bidderRequestId': '1144f487e563f9',
+ 'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d',
+ 'mediaTypes': {
+ 'banner': {
+ }
+ },
+ 'ad': '"

"'
+ }
+ ];
+
+ const testModeBidRequests = [
+ {
+ 'bidder': spec.code,
+ 'adUnitCode': 'adunit-code',
+ 'sizes': [[640, 480]],
+ 'params': {
+ 'org': 'jdye8weeyirk00000001',
+ 'testMode': true
+ },
+ 'bidId': '299ffc8cca0b87',
+ 'bidderRequestId': '1144f487e563f9',
+ 'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d',
+ }
+ ];
+
+ const bidderRequest = {
+ bidderCode: 'shinez',
+ }
+ const placementId = '12345678';
+
+ it('sends the placementId to ENDPOINT via POST', function () {
+ bidRequests[0].params.placementId = placementId;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.bids[0].placementId).to.equal(placementId);
+ });
+
+ it('sends bid request to ENDPOINT via POST', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.url).to.equal(ENDPOINT);
+ expect(request.method).to.equal('POST');
+ });
+
+ it('sends bid request to TEST ENDPOINT via POST', function () {
+ const request = spec.buildRequests(testModeBidRequests, bidderRequest);
+ expect(request.url).to.equal(TEST_ENDPOINT);
+ expect(request.method).to.equal('POST');
+ });
+
+ it('should send the correct bid Id', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.bids[0].bidId).to.equal('299ffc8cca0b87');
+ });
+
+ it('should send the correct sizes array', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.bids[0].sizes).to.be.an('array');
+ expect(request.data.bids[0].sizes).to.equal(bidRequests[0].sizes)
+ expect(request.data.bids[1].sizes).to.be.an('array');
+ expect(request.data.bids[1].sizes).to.equal(bidRequests[1].sizes)
+ });
+
+ it('should send the correct media type', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.bids[0].mediaType).to.equal(VIDEO)
+ expect(request.data.bids[1].mediaType).to.equal(BANNER)
+ });
+
+ it('should respect syncEnabled option', function() {
+ config.setConfig({
+ userSync: {
+ syncEnabled: false,
+ filterSettings: {
+ all: {
+ bidders: '*',
+ filter: 'include'
+ }
+ }
+ }
+ });
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.not.have.property('cs_method');
+ });
+
+ it('should respect "iframe" filter settings', function () {
+ config.setConfig({
+ userSync: {
+ syncEnabled: true,
+ filterSettings: {
+ iframe: {
+ bidders: [spec.code],
+ filter: 'include'
+ }
+ }
+ }
+ });
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.have.property('cs_method', 'iframe');
+ });
+
+ it('should respect "all" filter settings', function () {
+ config.setConfig({
+ userSync: {
+ syncEnabled: true,
+ filterSettings: {
+ all: {
+ bidders: [spec.code],
+ filter: 'include'
+ }
+ }
+ }
+ });
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.have.property('cs_method', 'iframe');
+ });
+
+ it('should send the pixel user sync param if userSync is enabled and no "iframe" or "all" configs are present', function () {
+ config.resetConfig();
+ config.setConfig({
+ userSync: {
+ syncEnabled: true,
+ }
+ });
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.have.property('cs_method', 'pixel');
+ });
+
+ it('should respect total exclusion', function() {
+ config.setConfig({
+ userSync: {
+ syncEnabled: true,
+ filterSettings: {
+ image: {
+ bidders: [spec.code],
+ filter: 'exclude'
+ },
+ iframe: {
+ bidders: [spec.code],
+ filter: 'exclude'
+ }
+ }
+ }
+ });
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.not.have.property('cs_method');
+ });
+
+ it('should have us_privacy param if usPrivacy is available in the bidRequest', function () {
+ const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest);
+ const request = spec.buildRequests(bidRequests, bidderRequestWithUSP);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.have.property('us_privacy', '1YNN');
+ });
+
+ it('should have an empty us_privacy param if usPrivacy is missing in the bidRequest', function () {
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.not.have.property('us_privacy');
+ });
+
+ it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () {
+ const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest);
+ const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.not.have.property('gdpr');
+ expect(request.data.params).to.not.have.property('gdpr_consent');
+ });
+
+ it('should send the gdpr param if gdprApplies is true in the bidRequest', function () {
+ const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}, bidderRequest);
+ const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.have.property('gdpr', true);
+ expect(request.data.params).to.have.property('gdpr_consent', 'test-consent-string');
+ });
+
+ it('should have schain param if it is available in the bidRequest', () => {
+ const schain = {
+ ver: '1.0',
+ complete: 1,
+ nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }],
+ };
+ bidRequests[0].schain = schain;
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.params).to.be.an('object');
+ expect(request.data.params).to.have.property('schain', '1.0,1!indirectseller.com,00001,1,,,');
+ });
+
+ it('should set flooPrice to getFloor.floor value if it is greater than params.floorPrice', function() {
+ const bid = utils.deepClone(bidRequests[0]);
+ bid.getFloor = () => {
+ return {
+ currency: 'USD',
+ floor: 3.32
+ }
+ }
+ bid.params.floorPrice = 0.64;
+ const request = spec.buildRequests([bid], bidderRequest);
+ expect(request.data.bids[0]).to.be.an('object');
+ expect(request.data.bids[0]).to.have.property('floorPrice', 3.32);
+ });
+
+ it('should set floorPrice to params.floorPrice value if it is greater than getFloor.floor', function() {
+ const bid = utils.deepClone(bidRequests[0]);
+ bid.getFloor = () => {
+ return {
+ currency: 'USD',
+ floor: 0.8
+ }
+ }
+ bid.params.floorPrice = 1.5;
+ const request = spec.buildRequests([bid], bidderRequest);
+ expect(request.data.bids[0]).to.be.an('object');
+ expect(request.data.bids[0]).to.have.property('floorPrice', 1.5);
+ });
+ });
+
+ describe('interpretResponse', function () {
+ const response = {
+ params: {
+ currency: 'USD',
+ netRevenue: true,
+ },
+ bids: [{
+ cpm: 12.5,
+ vastXml: '
',
+ width: 640,
+ height: 480,
+ requestId: '21e12606d47ba7',
+ adomain: ['abc.com'],
+ mediaType: VIDEO
+ },
+ {
+ cpm: 12.5,
+ ad: '"

"',
+ width: 300,
+ height: 250,
+ requestId: '21e12606d47ba7',
+ adomain: ['abc.com'],
+ mediaType: BANNER
+ }]
+ };
+
+ const expectedVideoResponse = {
+ requestId: '21e12606d47ba7',
+ cpm: 12.5,
+ currency: 'USD',
+ width: 640,
+ height: 480,
+ ttl: TTL,
+ creativeId: '21e12606d47ba7',
+ netRevenue: true,
+ nurl: 'http://example.com/win/1234',
+ mediaType: VIDEO,
+ meta: {
+ mediaType: VIDEO,
+ advertiserDomains: ['abc.com']
+ },
+ vastXml: '
',
+ };
+
+ const expectedBannerResponse = {
+ requestId: '21e12606d47ba7',
+ cpm: 12.5,
+ currency: 'USD',
+ width: 640,
+ height: 480,
+ ttl: TTL,
+ creativeId: '21e12606d47ba7',
+ netRevenue: true,
+ nurl: 'http://example.com/win/1234',
+ mediaType: BANNER,
+ meta: {
+ mediaType: BANNER,
+ advertiserDomains: ['abc.com']
+ },
+ ad: '"

"'
+ };
+
+ it('should get correct bid response', function () {
+ const result = spec.interpretResponse({ body: response });
+ expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedVideoResponse));
+ expect(Object.keys(result[1])).to.deep.equal(Object.keys(expectedBannerResponse));
+ });
+
+ it('video type should have vastXml key', function () {
+ const result = spec.interpretResponse({ body: response });
+ expect(result[0].vastXml).to.equal(expectedVideoResponse.vastXml)
+ });
+
+ it('banner type should have ad key', function () {
+ const result = spec.interpretResponse({ body: response });
+ expect(result[1].ad).to.equal(expectedBannerResponse.ad)
+ });
+ })
+
+ describe('getUserSyncs', function() {
+ const imageSyncResponse = {
+ body: {
+ params: {
+ userSyncPixels: [
+ 'https://image-sync-url.test/1',
+ 'https://image-sync-url.test/2',
+ 'https://image-sync-url.test/3'
+ ]
+ }
+ }
+ };
+
+ const iframeSyncResponse = {
+ body: {
+ params: {
+ userSyncURL: 'https://iframe-sync-url.test'
+ }
+ }
+ };
+
+ it('should register all img urls from the response', function() {
+ const syncs = spec.getUserSyncs({ pixelEnabled: true }, [imageSyncResponse]);
+ expect(syncs).to.deep.equal([
+ {
+ type: 'image',
+ url: 'https://image-sync-url.test/1'
+ },
+ {
+ type: 'image',
+ url: 'https://image-sync-url.test/2'
+ },
+ {
+ type: 'image',
+ url: 'https://image-sync-url.test/3'
+ }
+ ]);
+ });
+
+ it('should register the iframe url from the response', function() {
+ const syncs = spec.getUserSyncs({ iframeEnabled: true }, [iframeSyncResponse]);
+ expect(syncs).to.deep.equal([
+ {
+ type: 'iframe',
+ url: 'https://iframe-sync-url.test'
+ }
+ ]);
+ });
+
+ it('should register both image and iframe urls from the responses', function() {
+ const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [iframeSyncResponse, imageSyncResponse]);
+ expect(syncs).to.deep.equal([
+ {
+ type: 'iframe',
+ url: 'https://iframe-sync-url.test'
+ },
+ {
+ type: 'image',
+ url: 'https://image-sync-url.test/1'
+ },
+ {
+ type: 'image',
+ url: 'https://image-sync-url.test/2'
+ },
+ {
+ type: 'image',
+ url: 'https://image-sync-url.test/3'
+ }
+ ]);
+ });
+
+ it('should handle an empty response', function() {
+ const syncs = spec.getUserSyncs({ iframeEnabled: true }, []);
+ expect(syncs).to.deep.equal([]);
+ });
+
+ it('should handle when user syncs are disabled', function() {
+ const syncs = spec.getUserSyncs({ pixelEnabled: false }, [imageSyncResponse]);
+ expect(syncs).to.deep.equal([]);
+ });
+ })
+
+ describe('onBidWon', function() {
+ beforeEach(function() {
+ sinon.stub(utils, 'triggerPixel');
+ });
+ afterEach(function() {
+ utils.triggerPixel.restore();
+ });
+
+ it('Should trigger pixel if bid nurl', function() {
+ const bid = {
+ 'bidder': spec.code,
+ 'adUnitCode': 'adunit-code',
+ 'sizes': [['640', '480']],
+ 'nurl': 'http://example.com/win/1234',
+ 'params': {
+ 'org': 'jdye8weeyirk00000001'
+ }
+ };
+
+ spec.onBidWon(bid);
+ expect(utils.triggerPixel.callCount).to.equal(1)
+ })
+ })
+});
diff --git a/test/spec/modules/showheroes-bsBidAdapter_spec.js b/test/spec/modules/showheroes-bsBidAdapter_spec.js
index 69e8343dfc9..1aa7b132221 100644
--- a/test/spec/modules/showheroes-bsBidAdapter_spec.js
+++ b/test/spec/modules/showheroes-bsBidAdapter_spec.js
@@ -48,6 +48,18 @@ const bidRequestCommonParams = {
'auctionId': '43aa080090a47f',
}
+const bidRequestCommonParamsV2 = {
+ 'bidder': 'showheroes-bs',
+ 'params': {
+ 'unitId': 'AACBWAcof-611K4U',
+ },
+ 'adUnitCode': 'adunit-code-1',
+ 'sizes': [[640, 480]],
+ 'bidId': '38b373e1e31c18',
+ 'bidderRequestId': '12e3ade2543ba6',
+ 'auctionId': '43aa080090a47f',
+}
+
const bidRequestVideo = {
...bidRequestCommonParams,
...{
@@ -72,6 +84,30 @@ const bidRequestOutstream = {
}
}
+const bidRequestVideoV2 = {
+ ...bidRequestCommonParamsV2,
+ ...{
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480],
+ 'context': 'instream',
+ }
+ }
+ }
+}
+
+const bidRequestOutstreamV2 = {
+ ...bidRequestCommonParamsV2,
+ ...{
+ 'mediaTypes': {
+ 'video': {
+ 'playerSize': [640, 480],
+ 'context': 'outstream'
+ }
+ }
+ }
+}
+
const bidRequestVideoVpaid = {
...bidRequestCommonParams,
...{
@@ -129,12 +165,19 @@ describe('shBidAdapter', function () {
describe('isBidRequestValid', function () {
it('should return true when required params found', function () {
- const request = {
+ const requestV1 = {
'params': {
'playerId': '47427aa0-f11a-4d24-abca-1295a46a46cd',
}
}
- expect(spec.isBidRequestValid(request)).to.equal(true)
+ expect(spec.isBidRequestValid(requestV1)).to.equal(true)
+
+ const requestV2 = {
+ 'params': {
+ 'unitId': 'AACBTwsZVANd9NlB',
+ }
+ }
+ expect(spec.isBidRequestValid(requestV2)).to.equal(true)
})
it('should return false when required params are not passed', function () {
@@ -149,6 +192,9 @@ describe('shBidAdapter', function () {
it('sends bid request to ENDPOINT via POST', function () {
const request = spec.buildRequests([bidRequestVideo], bidderRequest)
expect(request.method).to.equal('POST')
+
+ const requestV2 = spec.buildRequests([bidRequestVideoV2], bidderRequest)
+ expect(requestV2.method).to.equal('POST')
})
it('check sizes formats', function () {
@@ -268,6 +314,30 @@ describe('shBidAdapter', function () {
expect(payload2).to.have.property('type', 5);
})
+ it('should attach valid params to the payload when type is video (instream V2)', function () {
+ const request = spec.buildRequests([bidRequestVideoV2], bidderRequest)
+ const payload = request.data.bidRequests[0];
+ expect(payload).to.be.an('object');
+ expect(payload).to.have.property('unitId', 'AACBWAcof-611K4U');
+ expect(payload.mediaTypes).to.eql({
+ [VIDEO]: {
+ 'context': 'instream'
+ }
+ });
+ })
+
+ it('should attach valid params to the payload when type is video (outstream V2)', function () {
+ const request = spec.buildRequests([bidRequestOutstreamV2], bidderRequest)
+ const payload = request.data.bidRequests[0];
+ expect(payload).to.be.an('object');
+ expect(payload).to.have.property('unitId', 'AACBWAcof-611K4U');
+ expect(payload.mediaTypes).to.eql({
+ [VIDEO]: {
+ 'context': 'outstream'
+ }
+ });
+ })
+
it('passes gdpr if present', function () {
const request = spec.buildRequests([bidRequestVideo], {...bidderRequest, ...gdpr})
const payload = request.data.requests[0];
@@ -275,6 +345,13 @@ describe('shBidAdapter', function () {
expect(payload.gdprConsent).to.eql(gdpr.gdprConsent)
})
+ it('passes gdpr if present (V2)', function () {
+ const request = spec.buildRequests([bidRequestVideoV2], {...bidderRequest, ...gdpr})
+ const context = request.data.context;
+ expect(context).to.be.an('object');
+ expect(context.gdprConsent).to.eql(gdpr.gdprConsent)
+ })
+
it('passes schain object if present', function() {
const request = spec.buildRequests([{
...bidRequestVideo,
@@ -284,6 +361,16 @@ describe('shBidAdapter', function () {
expect(payload).to.be.an('object');
expect(payload.schain).to.eql(schain.schain);
})
+
+ it('passes schain object if present (V2)', function() {
+ const request = spec.buildRequests([{
+ ...bidRequestVideoV2,
+ ...schain
+ }], bidderRequest)
+ const context = request.data.context;
+ expect(context).to.be.an('object');
+ expect(context.schain).to.eql(schain.schain);
+ })
})
describe('interpretResponse', function () {
@@ -327,6 +414,39 @@ describe('shBidAdapter', function () {
}],
};
+ const basicResponseV2 = {
+ 'requestId': '38b373e1e31c18',
+ 'adUnitCode': 'adunit-code-1',
+ 'cpm': 1,
+ 'currency': 'EUR',
+ 'width': 640,
+ 'height': 480,
+ 'advertiserDomain': [],
+ 'callbacks': {
+ 'won': ['https://api-n729.qa.viralize.com/track/?ver=15&session_id=01ecd03ce381505ccdeb88e555b05001&category=request_session&type=event&request_session_id=01ecd03ce381505ccdeb88e555b05001&label=prebid_won&reason=ok']
+ },
+ 'mediaType': 'video',
+ 'adomain': adomain,
+ };
+
+ const vastUrl = 'https://api-n729.qa.viralize.com/vast/?zid=AACBWAcof-611K4U&u=https://example.org/?foo=bar&gdpr=0&cs=XXXXXXXXXXXXXXXXXXXX&sid=01ecd03ce381505ccdeb88e555b05001&width=300&height=200&prebidmode=1'
+
+ const responseVideoV2 = {
+ 'bidResponses': [{
+ ...basicResponseV2,
+ 'context': 'instream',
+ 'vastUrl': vastUrl,
+ }],
+ };
+
+ const responseVideoOutstreamV2 = {
+ 'bidResponses': [{
+ ...basicResponseV2,
+ 'context': 'outstream',
+ 'ad': '',
+ }],
+ };
+
it('should get correct bid response when type is video', function () {
const request = spec.buildRequests([bidRequestVideo], bidderRequest)
const expectedResponse = [
@@ -356,6 +476,31 @@ describe('shBidAdapter', function () {
expect(result).to.deep.equal(expectedResponse)
})
+ it('should get correct bid response when type is video (V2)', function () {
+ const request = spec.buildRequests([bidRequestVideoV2], bidderRequest)
+ const expectedResponse = [
+ {
+ 'cpm': 1,
+ 'creativeId': 'c_38b373e1e31c18',
+ 'adUnitCode': 'adunit-code-1',
+ 'currency': 'EUR',
+ 'width': 640,
+ 'height': 480,
+ 'mediaType': 'video',
+ 'netRevenue': true,
+ 'vastUrl': vastUrl,
+ 'requestId': '38b373e1e31c18',
+ 'ttl': 300,
+ 'meta': {
+ 'advertiserDomains': adomain
+ }
+ }
+ ]
+
+ const result = spec.interpretResponse({'body': responseVideoV2}, request)
+ expect(result).to.deep.equal(expectedResponse)
+ })
+
it('should get correct bid response when type is banner', function () {
const request = spec.buildRequests([bidRequestBanner], bidderRequest)
@@ -396,6 +541,32 @@ describe('shBidAdapter', function () {
expect(spots.length).to.equal(1)
})
+ it('should get correct bid response when type is outstream (slot V2)', function () {
+ const bidRequestV2 = JSON.parse(JSON.stringify(bidRequestOutstreamV2));
+ const slotId = 'testSlot2'
+ bidRequestV2.params.outstreamOptions = {
+ slot: slotId
+ }
+
+ const container = document.createElement('div')
+ container.setAttribute('id', slotId)
+ document.body.appendChild(container)
+
+ const request = spec.buildRequests([bidRequestV2], bidderRequest)
+
+ const result = spec.interpretResponse({'body': responseVideoOutstreamV2}, request)
+ const bid = result[0]
+ expect(bid).to.have.property('mediaType', VIDEO);
+
+ const renderer = bid.renderer
+ expect(renderer).to.be.an('object')
+ expect(renderer.id).to.equal(bidRequestV2.bidId)
+ renderer.render(bid)
+
+ const scripts = container.querySelectorAll('#testScript')
+ expect(scripts.length).to.equal(1)
+ })
+
it('should get correct bid response when type is outstream (iframe)', function () {
const bidRequest = JSON.parse(JSON.stringify(bidRequestOutstream));
const slotId = 'testIframe'
diff --git a/test/spec/modules/sigmoidAnalyticsAdapter_spec.js b/test/spec/modules/sigmoidAnalyticsAdapter_spec.js
index 854c3a8e22d..6d772de02eb 100644
--- a/test/spec/modules/sigmoidAnalyticsAdapter_spec.js
+++ b/test/spec/modules/sigmoidAnalyticsAdapter_spec.js
@@ -38,7 +38,7 @@ describe('sigmoid Prebid Analytic', function () {
events.emit(constants.EVENTS.BID_RESPONSE, {});
events.emit(constants.EVENTS.BID_WON, {});
- sinon.assert.callCount(sigmoidAnalytic.track, 7);
+ sinon.assert.callCount(sigmoidAnalytic.track, 8);
});
});
describe('build utm tag data', function () {
diff --git a/test/spec/modules/sirdataRtdProvider_spec.js b/test/spec/modules/sirdataRtdProvider_spec.js
index a16359c50cb..9cf392ebd62 100644
--- a/test/spec/modules/sirdataRtdProvider_spec.js
+++ b/test/spec/modules/sirdataRtdProvider_spec.js
@@ -42,7 +42,7 @@ describe('sirdataRtdProvider', function() {
contextual_categories: {'333333': 100}
};
- addSegmentData(adUnits, data, config, () => {});
+ addSegmentData({adUnits}, data, config, () => {});
expect(adUnits[0].bids[0].params.keywords).to.have.deep.property('sd_rtd', ['111111', '222222', '333333']);
expect(adUnits[0].bids[1].ortb2.site.ext.data).to.have.deep.property('sd_rtd', ['333333']);
expect(adUnits[0].bids[1].ortb2.user.ext.data).to.have.deep.property('sd_rtd', ['111111', '222222']);
diff --git a/test/spec/modules/sizeMappingV2_spec.js b/test/spec/modules/sizeMappingV2_spec.js
index 9bbd472c7e0..27fd7a33c14 100644
--- a/test/spec/modules/sizeMappingV2_spec.js
+++ b/test/spec/modules/sizeMappingV2_spec.js
@@ -616,6 +616,9 @@ describe('sizeMappingV2', function () {
});
describe('native mediaTypes checks', function () {
+ if (!FEATURES.NATIVE) {
+ return;
+ }
beforeEach(function () {
sinon.spy(adUnitSetupChecks, 'validateNativeMediaType');
});
diff --git a/test/spec/modules/slimcutBidAdapter_spec.js b/test/spec/modules/slimcutBidAdapter_spec.js
index 300791c9658..d821627c24b 100644
--- a/test/spec/modules/slimcutBidAdapter_spec.js
+++ b/test/spec/modules/slimcutBidAdapter_spec.js
@@ -106,7 +106,7 @@ describe('slimcutBidAdapter', function() {
const bidRequest = Object.assign({}, bidRequests[0])
const bidderRequest = {
refererInfo: {
- referer: 'https://example.com/page.html',
+ page: 'https://example.com/page.html',
reachedTop: true,
numIframes: 2
}
diff --git a/test/spec/modules/smaatoBidAdapter_spec.js b/test/spec/modules/smaatoBidAdapter_spec.js
index 38df03652b1..99592765845 100644
--- a/test/spec/modules/smaatoBidAdapter_spec.js
+++ b/test/spec/modules/smaatoBidAdapter_spec.js
@@ -18,7 +18,7 @@ const defaultBidderRequest = {
},
uspConsent: 'uspConsentString',
refererInfo: {
- referer: REFERRER,
+ ref: REFERRER,
},
timeout: 1200,
auctionId: AUCTION_ID
@@ -123,7 +123,7 @@ describe('smaatoBidAdapterTest', () => {
describe('common', () => {
const MINIMAL_BIDDER_REQUEST = {
refererInfo: {
- referer: REFERRER,
+ ref: REFERRER,
}
};
@@ -328,27 +328,22 @@ describe('smaatoBidAdapterTest', () => {
});
it('sends first party data', () => {
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- ortb2: {
- site: {
- keywords: 'power tools,drills',
- publisher: {
- id: 'otherpublisherid',
- name: 'publishername'
- }
- },
- user: {
- keywords: 'a,b',
- gender: 'M',
- yob: 1984
- }
+ const ortb2 = {
+ site: {
+ keywords: 'power tools,drills',
+ publisher: {
+ id: 'otherpublisherid',
+ name: 'publishername'
}
- };
- return utils.deepAccess(config, key);
- });
+ },
+ user: {
+ keywords: 'a,b',
+ gender: 'M',
+ yob: 1984
+ }
+ };
- const reqs = spec.buildRequests([singleBannerBidRequest], defaultBidderRequest);
+ const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2});
const req = extractPayloadOfFirstAndOnlyRequest(reqs);
expect(req.user.gender).to.equal('M');
diff --git a/test/spec/modules/smarthubBidAdapter_spec.js b/test/spec/modules/smarthubBidAdapter_spec.js
index 05fb1424dca..e1787dfe880 100644
--- a/test/spec/modules/smarthubBidAdapter_spec.js
+++ b/test/spec/modules/smarthubBidAdapter_spec.js
@@ -90,7 +90,7 @@ describe('SmartHubBidAdapter', function () {
uspConsent: '1---',
gdprConsent: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw',
refererInfo: {
- referer: 'https://test.com'
+ page: 'https://test.com'
}
};
diff --git a/test/spec/modules/smartxBidAdapter_spec.js b/test/spec/modules/smartxBidAdapter_spec.js
index ddee2fa3347..58ce50efb8e 100644
--- a/test/spec/modules/smartxBidAdapter_spec.js
+++ b/test/spec/modules/smartxBidAdapter_spec.js
@@ -145,7 +145,7 @@ describe('The smartx adapter', function () {
bid = getValidBidObject();
bidRequestObj = {
refererInfo: {
- referer: 'prebid.js'
+ page: 'prebid.js'
}
};
});
@@ -514,7 +514,7 @@ describe('The smartx adapter', function () {
responses[0].renderer.render(responses[0]);
- expect(responses[0].renderer.url).to.equal('https://dco.smartclip.net/?plc=7777778');
+ expect(responses[0].renderer.url).to.equal('https://dco.smartclip.net/?plc=7777779');
window.document.getElementById.restore();
});
@@ -542,7 +542,7 @@ describe('The smartx adapter', function () {
responses[0].renderer.render(responses[0]);
- expect(responses[0].renderer.url).to.equal('https://dco.smartclip.net/?plc=7777778');
+ expect(responses[0].renderer.url).to.equal('https://dco.smartclip.net/?plc=7777779');
window.document.getElementById.restore();
});
@@ -560,7 +560,7 @@ describe('The smartx adapter', function () {
responses[0].renderer.render(responses[0]);
- expect(responses[0].renderer.url).to.equal('https://dco.smartclip.net/?plc=7777778');
+ expect(responses[0].renderer.url).to.equal('https://dco.smartclip.net/?plc=7777779');
window.document.getElementById.restore();
});
@@ -574,7 +574,7 @@ describe('The smartx adapter', function () {
bid = getValidBidObject();
bidRequestObj = {
refererInfo: {
- referer: 'prebid.js'
+ page: 'prebid.js'
}
};
delete bid.params.bidfloor;
diff --git a/test/spec/modules/smilewantedBidAdapter_spec.js b/test/spec/modules/smilewantedBidAdapter_spec.js
index 0359e470f9b..b9a816cf3d5 100644
--- a/test/spec/modules/smilewantedBidAdapter_spec.js
+++ b/test/spec/modules/smilewantedBidAdapter_spec.js
@@ -163,7 +163,7 @@ describe('smilewantedBidAdapterTests', function () {
it('SmileWanted - Verify build request with referrer', function () {
const request = spec.buildRequests(DISPLAY_REQUEST, {
refererInfo: {
- referer: 'https://localhost/Prebid.js/integrationExamples/gpt/hello_world.html'
+ page: 'https://localhost/Prebid.js/integrationExamples/gpt/hello_world.html'
}
});
const requestContent = JSON.parse(request[0].data);
diff --git a/test/spec/modules/snigelBidAdapter_spec.js b/test/spec/modules/snigelBidAdapter_spec.js
new file mode 100644
index 00000000000..3fc09493f03
--- /dev/null
+++ b/test/spec/modules/snigelBidAdapter_spec.js
@@ -0,0 +1,296 @@
+import {expect} from 'chai';
+import {spec} from 'modules/snigelBidAdapter.js';
+import {config} from 'src/config.js';
+import {isValid} from 'src/adapters/bidderFactory.js';
+
+const BASE_BID_REQUEST = {
+ adUnitCode: 'top_leaderboard',
+ bidId: 'bid_test',
+ sizes: [
+ [970, 90],
+ [728, 90],
+ ],
+ bidder: 'snigel',
+ params: {},
+ requestId: 'req_test',
+ transactionId: 'trans_test',
+};
+const makeBidRequest = function (overrides) {
+ return {...BASE_BID_REQUEST, ...overrides};
+};
+
+const BASE_BIDDER_REQUEST = {
+ bidderRequestId: 'test',
+ refererInfo: {
+ canonicalUrl: 'https://localhost',
+ },
+};
+const makeBidderRequest = function (overrides) {
+ return {...BASE_BIDDER_REQUEST, ...overrides};
+};
+
+const DUMMY_USP_CONSENT = '1YYN';
+const DUMMY_GDPR_CONSENT_STRING =
+ 'BOSSotLOSSotLAPABAENBc-AAAAgR7_______9______9uz_Gv_v_f__33e8__9v_l_7_-___u_-33d4-_1vX99yfm1-7ftr3tp_86ues2_XqK_9oIiA';
+
+describe('snigelBidAdapter', function () {
+ describe('isBidRequestValid', function () {
+ it('should return false if no placement provided', function () {
+ expect(spec.isBidRequestValid(BASE_BID_REQUEST)).to.equal(false);
+ });
+
+ it('should return true if placement provided', function () {
+ const bidRequest = makeBidRequest({params: {placement: 'top_leaderboard'}});
+ expect(spec.isBidRequestValid(bidRequest)).to.equal(true);
+ });
+ });
+
+ describe('buildRequests', function () {
+ afterEach(function () {
+ config.resetConfig();
+ });
+
+ it('should build a single request for every impression and its placement', function () {
+ const bidderRequest = Object.assign({}, BASE_BIDDER_REQUEST);
+ const bidRequests = [
+ makeBidRequest({bidId: 'a', params: {placement: 'top_leaderboard'}}),
+ makeBidRequest({bidId: 'b', params: {placement: 'bottom_leaderboard'}}),
+ ];
+
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request).to.be.an('object');
+ expect(request).to.have.property('url').and.to.equal('https://adserv.snigelweb.com/bp/v1/prebid');
+ expect(request).to.have.property('method').and.to.equal('POST');
+
+ expect(request).to.have.property('data');
+ const data = JSON.parse(request.data);
+ expect(data).to.have.property('id').and.to.equal('test');
+ expect(data).to.have.property('cur').and.to.deep.equal(['USD']);
+ expect(data).to.have.property('test').and.to.equal(false);
+ expect(data).to.have.property('page').and.to.equal('https://localhost');
+ expect(data).to.have.property('placements');
+ expect(data.placements.length).to.equal(2);
+ expect(data.placements[0].uuid).to.equal('a');
+ expect(data.placements[0].name).to.equal('top_leaderboard');
+ expect(data.placements[1].uuid).to.equal('b');
+ expect(data.placements[1].name).to.equal('bottom_leaderboard');
+ });
+
+ it('should forward GDPR flag and GDPR consent string if enabled', function () {
+ const bidderRequest = makeBidderRequest({
+ gdprConsent: {
+ gdprApplies: true,
+ consentString: DUMMY_GDPR_CONSENT_STRING,
+ },
+ });
+
+ const request = spec.buildRequests([], bidderRequest);
+ expect(request).to.have.property('data');
+ const data = JSON.parse(request.data);
+ expect(data).to.have.property('gdprApplies').and.to.equal(true);
+ expect(data).to.have.property('gdprConsentString').and.to.equal(DUMMY_GDPR_CONSENT_STRING);
+ });
+
+ it('should forward GDPR flag and no GDPR consent string if disabled', function () {
+ const bidderRequest = makeBidderRequest({
+ gdprConsent: {
+ gdprApplies: false,
+ consentString: DUMMY_GDPR_CONSENT_STRING,
+ },
+ });
+
+ const request = spec.buildRequests([], bidderRequest);
+ expect(request).to.have.property('data');
+ const data = JSON.parse(request.data);
+ expect(data).to.have.property('gdprApplies').and.to.equal(false);
+ expect(data).to.not.have.property('gdprConsentString');
+ });
+
+ it('should forward USP consent if set', function () {
+ const bidderRequest = makeBidderRequest({
+ uspConsent: DUMMY_USP_CONSENT,
+ });
+
+ const request = spec.buildRequests([], bidderRequest);
+ expect(request).to.have.property('data');
+ const data = JSON.parse(request.data);
+ expect(data).to.have.property('uspConsent').and.to.equal(DUMMY_USP_CONSENT);
+ });
+
+ it('should forward whether or not COPPA applies', function () {
+ config.setConfig({
+ 'coppa': true,
+ });
+
+ const request = spec.buildRequests([], BASE_BIDDER_REQUEST);
+ expect(request).to.have.property('data');
+ const data = JSON.parse(request.data);
+ expect(data).to.have.property('coppa').and.to.equal(true);
+ });
+ });
+
+ describe('interpretResponse', function () {
+ it('should not return any bids if the request failed', function () {
+ expect(spec.interpretResponse({}, {})).to.be.empty;
+ expect(spec.interpretResponse({body: 'Some error message'}, {})).to.be.empty;
+ });
+
+ it('should not return any bids if the request did not return any bids either', function () {
+ expect(spec.interpretResponse({body: {bids: []}})).to.be.empty;
+ });
+
+ it('should return valid bids with additional meta information', function () {
+ const serverResponse = {
+ body: {
+ id: BASE_BIDDER_REQUEST.bidderRequestId,
+ cur: 'USD',
+ bids: [
+ {
+ uuid: BASE_BID_REQUEST.bidId,
+ price: 0.0575,
+ ad: '
Test Ad
',
+ width: 728,
+ height: 90,
+ crid: 'test',
+ meta: {
+ advertiserDomains: ['addomain.com'],
+ },
+ },
+ ],
+ },
+ };
+
+ const bids = spec.interpretResponse(serverResponse, {});
+ expect(bids.length).to.equal(1);
+ const bid = bids[0];
+ expect(isValid(BASE_BID_REQUEST.adUnitCode, bid)).to.be.true;
+ expect(bid).to.have.property('meta');
+ expect(bid.meta).to.have.property('advertiserDomains');
+ expect(bid.meta.advertiserDomains).to.be.an('array');
+ expect(bid.meta.advertiserDomains.length).to.equal(1);
+ expect(bid.meta.advertiserDomains[0]).to.equal('addomain.com');
+ });
+ });
+
+ describe('getUserSyncs', function () {
+ it('should not return any user syncs if sync url does not exist in response', function () {
+ const response = {
+ body: {
+ id: BASE_BIDDER_REQUEST.bidderRequestId,
+ cur: 'USD',
+ bids: [],
+ },
+ };
+ const syncOptions = {
+ iframeEnabled: true,
+ };
+ const gdprConsent = {
+ gdprApplies: false,
+ };
+
+ const syncs = spec.getUserSyncs(syncOptions, [response], gdprConsent);
+ expect(syncs).to.be.undefined;
+ });
+
+ it('should not return any user syncs if publisher disabled iframe-based sync', function () {
+ const response = {
+ body: {
+ id: BASE_BIDDER_REQUEST.bidderRequestId,
+ cur: 'USD',
+ syncUrl: 'https://somesyncurl',
+ bids: [],
+ },
+ };
+ const syncOptions = {
+ iframeEnabled: false,
+ };
+ const gdprConsent = {
+ gdprApplies: false,
+ };
+
+ const syncs = spec.getUserSyncs(syncOptions, [response], gdprConsent);
+ expect(syncs).to.be.undefined;
+ });
+
+ it('should not return any user syncs if GDPR applies and the user did not consent to purpose one', function () {
+ const response = {
+ body: {
+ id: BASE_BIDDER_REQUEST.bidderRequestId,
+ cur: 'USD',
+ syncUrl: 'https://somesyncurl',
+ bids: [],
+ },
+ };
+ const syncOptions = {
+ iframeEnabled: true,
+ };
+ const gdprConsent = {
+ gdprApplies: true,
+ vendorData: {
+ purpose: {
+ consents: {1: false},
+ },
+ },
+ };
+
+ const syncs = spec.getUserSyncs(syncOptions, [response], gdprConsent);
+ expect(syncs).to.be.undefined;
+ });
+
+ it("should return an iframe specific to the publisher's property if all conditions are met", function () {
+ const response = {
+ body: {
+ id: BASE_BIDDER_REQUEST.bidderRequestId,
+ cur: 'USD',
+ syncUrl: 'https://somesyncurl',
+ bids: [],
+ },
+ };
+ const syncOptions = {
+ iframeEnabled: true,
+ };
+ const gdprConsent = {
+ gdprApplies: false,
+ };
+
+ const syncs = spec.getUserSyncs(syncOptions, [response], gdprConsent);
+ expect(syncs).to.be.an('array').and.of.length(1);
+ const sync = syncs[0];
+ expect(sync).to.have.property('type');
+ expect(sync.type).to.equal('iframe');
+ expect(sync).to.have.property('url');
+ expect(sync.url).to.equal('https://somesyncurl?gdpr=0&gdpr_consent=');
+ });
+
+ it('should pass GDPR applicability and consent string as query parameters', function () {
+ const response = {
+ body: {
+ id: BASE_BIDDER_REQUEST.bidderRequestId,
+ cur: 'USD',
+ syncUrl: 'https://somesyncurl',
+ bids: [],
+ },
+ };
+ const syncOptions = {
+ iframeEnabled: true,
+ };
+ const gdprConsent = {
+ gdprApplies: true,
+ consentString: DUMMY_GDPR_CONSENT_STRING,
+ vendorData: {
+ purpose: {
+ consents: {1: true},
+ },
+ },
+ };
+
+ const syncs = spec.getUserSyncs(syncOptions, [response], gdprConsent);
+ expect(syncs).to.be.an('array').and.of.length(1);
+ const sync = syncs[0];
+ expect(sync).to.have.property('type');
+ expect(sync.type).to.equal('iframe');
+ expect(sync).to.have.property('url');
+ expect(sync.url).to.equal(`https://somesyncurl?gdpr=1&gdpr_consent=${DUMMY_GDPR_CONSENT_STRING}`);
+ });
+ });
+});
diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js
index f56f4e0c12b..7803cfff394 100644
--- a/test/spec/modules/sonobiBidAdapter_spec.js
+++ b/test/spec/modules/sonobiBidAdapter_spec.js
@@ -1,7 +1,7 @@
import { expect } from 'chai'
import { spec, _getPlatform } from 'modules/sonobiBidAdapter.js'
import { newBidder } from 'src/adapters/bidderFactory.js'
-import {userSync} from '../../../src/userSync.js';
+import { userSync } from '../../../src/userSync.js';
import { config } from 'src/config.js';
import * as utils from '../../../src/utils.js';
@@ -239,13 +239,13 @@ describe('SonobiBidAdapter', function () {
describe('.buildRequests', function () {
let sandbox;
- beforeEach(function() {
+ beforeEach(function () {
sinon.stub(userSync, 'canBidderRegisterSync');
sinon.stub(utils, 'getGptSlotInfoForAdUnitCode')
- .onFirstCall().returns({gptSlot: '/123123/gpt_publisher/adunit-code-3', divId: 'adunit-code-3-div-id'});
+ .onFirstCall().returns({ gptSlot: '/123123/gpt_publisher/adunit-code-3', divId: 'adunit-code-3-div-id' });
sandbox = sinon.createSandbox();
});
- afterEach(function() {
+ afterEach(function () {
userSync.canBidderRegisterSync.restore();
utils.getGptSlotInfoForAdUnitCode.restore();
sandbox.restore();
@@ -284,6 +284,11 @@ describe('SonobiBidAdapter', function () {
pbadslot: '/123123/gpt_publisher/adunit-code-1'
}
}
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream'
+ }
}
},
{
@@ -296,11 +301,16 @@ describe('SonobiBidAdapter', function () {
'adUnitCode': 'adunit-code-3',
'sizes': [[120, 600], [300, 600], [160, 600]],
'bidId': '30b31c1838de1d',
- 'getFloor': ({currency, mediaType, size}) => {
+ 'getFloor': ({ currency, mediaType, size }) => {
return {
currency: 'USD',
floor: 0.42
}
+ },
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
}
},
{
@@ -313,12 +323,17 @@ describe('SonobiBidAdapter', function () {
'adUnitCode': 'adunit-code-2',
'sizes': [[120, 600], [300, 600], [160, 600]],
'bidId': '30b31c1838de1e',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250], [300, 600]]
+ }
+ }
}];
let keyMakerData = {
- '30b31c1838de1f': '1a2b3c4d5e6f1a2b3c4d|300x250,300x600|f=1.25|gpid=/123123/gpt_publisher/adunit-code-1',
- '30b31c1838de1d': '1a2b3c4d5e6f1a2b3c4e|300x250,300x600|f=0.42|gpid=/123123/gpt_publisher/adunit-code-3',
- '/7780971/sparks_prebid_LB|30b31c1838de1e': '300x250,300x600|gpid=/7780971/sparks_prebid_LB',
+ '30b31c1838de1f': '1a2b3c4d5e6f1a2b3c4d||f=1.25,gpid=/123123/gpt_publisher/adunit-code-1,c=v,',
+ '30b31c1838de1d': '1a2b3c4d5e6f1a2b3c4e|300x250,300x600|f=0.42,gpid=/123123/gpt_publisher/adunit-code-3,c=d,',
+ '/7780971/sparks_prebid_LB|30b31c1838de1e': '300x250,300x600|gpid=/7780971/sparks_prebid_LB,c=d,',
};
let bidderRequests = {
@@ -330,13 +345,13 @@ describe('SonobiBidAdapter', function () {
'refererInfo': {
'numIframes': 0,
'reachedTop': true,
- 'referer': 'https://example.com',
+ 'page': 'https://example.com',
'stack': ['https://example.com']
},
uspConsent: 'someCCPAString'
};
- it('should set fpd if there is any data in ortb2', function() {
+ it('should set fpd if there is any data in ortb2', function () {
const ortb2 = {
site: {
ext: {
@@ -355,26 +370,19 @@ describe('SonobiBidAdapter', function () {
}
}
};
-
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- ortb2: ortb2
- };
- return utils.deepAccess(config, key);
- });
- const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
+ const bidRequests = spec.buildRequests(bidRequest, {...bidderRequests, ortb2});
expect(bidRequests.data.fpd).to.equal(JSON.stringify(ortb2));
});
it('should populate coppa as 1 if set in config', function () {
- config.setConfig({coppa: true});
+ config.setConfig({ coppa: true });
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.coppa).to.equal(1);
});
it('should populate coppa as 0 if set in config', function () {
- config.setConfig({coppa: false});
+ config.setConfig({ coppa: false });
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.coppa).to.equal(0);
@@ -427,7 +435,7 @@ describe('SonobiBidAdapter', function () {
'refererInfo': {
'numIframes': 0,
'reachedTop': true,
- 'referer': 'https://example.com',
+ 'page': 'https://example.com',
'stack': ['https://example.com']
}
};
@@ -447,7 +455,7 @@ describe('SonobiBidAdapter', function () {
'refererInfo': {
'numIframes': 0,
'reachedTop': true,
- 'referer': 'https://example.com',
+ 'page': 'https://example.com',
'stack': ['https://example.com']
}
};
@@ -469,7 +477,7 @@ describe('SonobiBidAdapter', function () {
})
it('should return null if there is nothing to bid on', function () {
- const bidRequests = spec.buildRequests([{params: {}}], bidderRequests)
+ const bidRequests = spec.buildRequests([{ params: {} }], bidderRequests)
expect(bidRequests).to.equal(null);
});
@@ -479,7 +487,7 @@ describe('SonobiBidAdapter', function () {
expect(bidRequests.data.ius).to.equal(0);
});
- it('should set ius as 1 if Sonobi can drop iframe pixels', function() {
+ it('should set ius as 1 if Sonobi can drop iframe pixels', function () {
userSync.canBidderRegisterSync.returns(true);
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.ius).to.equal(1);
@@ -532,14 +540,14 @@ describe('SonobiBidAdapter', function () {
});
it('should return a properly formatted request with userid as a JSON-encoded set of User ID results', function () {
- bidRequest[0].userId = {'pubcid': 'abcd-efg-0101', 'tdid': 'td-abcd-efg-0101', 'id5id': {'uid': 'ID5-ZHMOrVeUVTUKgrZ-a2YGxeh5eS_pLzHCQGYOEAiTBQ', 'ext': {'linkType': 2}}};
- bidRequest[1].userId = {'pubcid': 'abcd-efg-0101', 'tdid': 'td-abcd-efg-0101', 'id5id': {'uid': 'ID5-ZHMOrVeUVTUKgrZ-a2YGxeh5eS_pLzHCQGYOEAiTBQ', 'ext': {'linkType': 2}}};
+ bidRequest[0].userId = { 'pubcid': 'abcd-efg-0101', 'tdid': 'td-abcd-efg-0101', 'id5id': { 'uid': 'ID5-ZHMOrVeUVTUKgrZ-a2YGxeh5eS_pLzHCQGYOEAiTBQ', 'ext': { 'linkType': 2 } } };
+ bidRequest[1].userId = { 'pubcid': 'abcd-efg-0101', 'tdid': 'td-abcd-efg-0101', 'id5id': { 'uid': 'ID5-ZHMOrVeUVTUKgrZ-a2YGxeh5eS_pLzHCQGYOEAiTBQ', 'ext': { 'linkType': 2 } } };
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.url).to.equal('https://apex.go.sonobi.com/trinity.json');
expect(bidRequests.method).to.equal('GET');
expect(bidRequests.data.ref).not.to.be.empty;
expect(bidRequests.data.s).not.to.be.empty;
- expect(JSON.parse(bidRequests.data.userid)).to.eql({'pubcid': 'abcd-efg-0101', 'tdid': 'td-abcd-efg-0101', 'id5id': 'ID5-ZHMOrVeUVTUKgrZ-a2YGxeh5eS_pLzHCQGYOEAiTBQ'});
+ expect(JSON.parse(bidRequests.data.userid)).to.eql({ 'pubcid': 'abcd-efg-0101', 'tdid': 'td-abcd-efg-0101', 'id5id': 'ID5-ZHMOrVeUVTUKgrZ-a2YGxeh5eS_pLzHCQGYOEAiTBQ' });
});
it('should return a properly formatted request with userid omitted if there are no userIds', function () {
@@ -564,17 +572,17 @@ describe('SonobiBidAdapter', function () {
expect(bidRequests.data.userid).to.equal(undefined);
});
- it('should return a properly formatted request with keywrods included as a csv of strings', function() {
+ it('should return a properly formatted request with keywrods included as a csv of strings', function () {
const bidRequests = spec.buildRequests(bidRequest, bidderRequests);
expect(bidRequests.data.kw).to.equal('sports,news,some_other_keyword');
});
- it('should return a properly formatted request with us_privacy included', function() {
+ 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 make a request to the url defined in the bidder param', function() {
+ it('should make a request to the url defined in the bidder param', function () {
const bRequest = [
{
...bidRequest[0],
@@ -762,7 +770,7 @@ describe('SonobiBidAdapter', function () {
'dealId': 'dozerkey',
'aid': 'force_1550072228_da1c5d030cb49150c5db8a2136175755',
'mediaType': 'video',
- renderer: () => {},
+ renderer: () => { },
meta: {
advertiserDomains: ['sonobi.com']
}
@@ -835,13 +843,13 @@ describe('SonobiBidAdapter', function () {
})
describe('_getPlatform', function () {
it('should return mobile', function () {
- expect(_getPlatform({innerWidth: 767})).to.equal('mobile')
+ expect(_getPlatform({ innerWidth: 767 })).to.equal('mobile')
})
it('should return tablet', function () {
- expect(_getPlatform({innerWidth: 800})).to.equal('tablet')
+ expect(_getPlatform({ innerWidth: 800 })).to.equal('tablet')
})
it('should return desktop', function () {
- expect(_getPlatform({innerWidth: 1000})).to.equal('desktop')
+ expect(_getPlatform({ innerWidth: 1000 })).to.equal('desktop')
})
})
})
diff --git a/test/spec/modules/sortableAnalyticsAdapter_spec.js b/test/spec/modules/sortableAnalyticsAdapter_spec.js
deleted file mode 100644
index 9300756eae2..00000000000
--- a/test/spec/modules/sortableAnalyticsAdapter_spec.js
+++ /dev/null
@@ -1,306 +0,0 @@
-import {expect} from 'chai';
-import sortableAnalyticsAdapter, {TIMEOUT_FOR_REGISTRY, DEFAULT_PBID_TIMEOUT} from 'modules/sortableAnalyticsAdapter.js';
-import * as events from 'src/events.js';
-import CONSTANTS from 'src/constants.json';
-import * as prebidGlobal from 'src/prebidGlobal.js';
-import {server} from 'test/mocks/xhr.js';
-
-describe('Sortable Analytics Adapter', function() {
- let sandbox;
- let clock;
-
- const initialConfig = {
- provider: 'sortable',
- options: {
- siteId: 'testkey'
- }
- };
-
- const TEST_DATA = {
- AUCTION_INIT: {
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- timeout: 3000
- },
- BID_REQUESTED: {
- refererInfo: {
- referer: 'test.com',
- reachedTop: true,
- numIframes: 1
- },
- bidderCode: 'sortable',
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- bids: [{
- bidder: 'sortable',
- params: {
- tagId: 'medrec_1'
- },
- adUnitCode: '300x250',
- transactionId: 'aa02b498-8a99-418e-bc59-6b6fd45f32de',
- sizes: [
- [300, 250]
- ],
- bidId: '26721042674416',
- bidderRequestId: '10141593b1d84a',
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- bidRequestsCount: 1
- }, {
- bidder: 'sortable',
- params: {
- tagId: 'lead_1'
- },
- adUnitCode: '728x90',
- transactionId: 'b7e9e957-af4f-4c47-8ca7-41f01cb4f105',
- sizes: [
- [728, 90]
- ],
- bidId: '50fa575b41e596',
- bidderRequestId: '37a8760be6db23',
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- bidRequestsCount: 1
- }],
- start: 1553529405788
- },
- BID_ADJUSTMENT_1: {
- bidderCode: 'sortable',
- adId: '88221d316425f7',
- mediaType: 'banner',
- cpm: 0.70,
- dealId: null,
- currency: 'USD',
- netRevenue: true,
- ttl: 60,
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- responseTimestamp: 1553534161763,
- bidder: 'sortable',
- adUnitCode: '300x250',
- timeToRespond: 331,
- width: '300',
- height: '250'
- },
- AUCTION_END: {
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e'
- },
- BID_ADJUSTMENT_2: {
- bidderCode: 'sortable',
- adId: '88221d316425f8',
- mediaType: 'banner',
- cpm: 0.50,
- dealId: null,
- currency: 'USD',
- netRevenue: true,
- ttl: 60,
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- responseTimestamp: 1553534161770,
- bidder: 'sortable',
- adUnitCode: '728x90',
- timeToRespond: 338,
- width: '728',
- height: '90'
- },
- BID_WON_1: {
- bidderCode: 'sortable',
- adId: '88221d316425f7',
- mediaType: 'banner',
- cpm: 0.70,
- dealId: null,
- currency: 'USD',
- netRevenue: true,
- ttl: 60,
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- responseTimestamp: 1553534161763,
- bidder: 'sortable',
- adUnitCode: '300x250',
- timeToRespond: 331
- },
- BID_WON_2: {
- bidderCode: 'sortable',
- adId: '88221d316425f8',
- mediaType: 'banner',
- cpm: 0.50,
- dealId: null,
- currency: 'USD',
- netRevenue: true,
- ttl: 60,
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- responseTimestamp: 1553534161770,
- bidder: 'sortable',
- adUnitCode: '728x90',
- timeToRespond: 338
- },
- BID_TIMEOUT: [{
- auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- adUnitCode: '300x250',
- bidder: 'sortable'
- }]
- };
-
- beforeEach(function() {
- sandbox = sinon.sandbox.create();
- clock = sandbox.useFakeTimers();
- sandbox.stub(events, 'getEvents').returns([]);
- sandbox.stub(prebidGlobal, 'getGlobal').returns({
- version: '1.0',
- bidderSettings: {
- 'sortable': {
- bidCpmAdjustment: function (number) {
- return number * 0.95;
- }
- }
- }
- });
- sortableAnalyticsAdapter.enableAnalytics(initialConfig);
- });
-
- afterEach(function() {
- sandbox.restore();
- clock.restore();
- sortableAnalyticsAdapter.disableAnalytics();
- });
-
- describe('initialize adapter', function() {
- const settings = sortableAnalyticsAdapter.getOptions();
-
- it('should init settings correctly and apply defaults', function() {
- expect(settings).to.include({
- 'disableSessionTracking': false,
- 'key': initialConfig.options.siteId,
- 'protocol': 'https',
- 'url': `https://pa.deployads.com/pae/${initialConfig.options.siteId}`,
- 'timeoutForPbid': DEFAULT_PBID_TIMEOUT
- });
- });
- it('should assign a pageview ID', function() {
- expect(settings).to.have.own.property('pageviewId');
- });
- });
-
- describe('events tracking', function() {
- beforeEach(function() {
- server.requests = [];
- });
- it('should send the PBID event', function() {
- events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT);
- events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED);
- events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_1);
- events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_2);
- events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END);
- events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_1);
- events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_2);
-
- clock.tick(DEFAULT_PBID_TIMEOUT);
-
- expect(server.requests.length).to.equal(1);
- let result = JSON.parse(server.requests[0].requestBody);
- expect(result).to.have.own.property('pbid');
- expect(result.pbid).to.deep.include({
- ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- ac: ['300x250', '728x90'],
- adi: ['88221d316425f7', '88221d316425f8'],
- bs: 'sortable',
- bid: ['26721042674416', '50fa575b41e596'],
- bif: 0.95,
- brc: 1,
- brid: ['10141593b1d84a', '37a8760be6db23'],
- rs: ['300x250', '728x90'],
- btcp: [0.70, 0.50].map(n => n * 0.95),
- btcc: 'USD',
- btin: true,
- btsrc: 'sortable',
- c: [0.70, 0.50].map(n => n * 0.95),
- cc: 'USD',
- did: null,
- inr: true,
- it: true,
- iw: true,
- ito: false,
- mt: 'banner',
- rtp: true,
- nif: 1,
- pbv: '1.0',
- siz: ['300x250', '728x90'],
- st: 1553529405788,
- tgid: ['medrec_1', 'lead_1'],
- to: 3000,
- trid: ['aa02b498-8a99-418e-bc59-6b6fd45f32de', 'b7e9e957-af4f-4c47-8ca7-41f01cb4f105'],
- ttl: 60,
- ttr: [331, 338],
- u: 'test.com',
- _count: 2
- });
- });
-
- it('should track a late bidWon event', function() {
- events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT);
- events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED);
- events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_1);
- events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END);
-
- clock.tick(DEFAULT_PBID_TIMEOUT);
-
- events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_1);
-
- clock.tick(TIMEOUT_FOR_REGISTRY);
-
- expect(server.requests.length).to.equal(2);
- const pbid_req = JSON.parse(server.requests[0].requestBody);
- expect(pbid_req).to.have.own.property('pbid');
- const pbwon_req = JSON.parse(server.requests[1].requestBody);
- expect(pbwon_req).to.have.own.property('pbrw');
- expect(pbwon_req.pbrw).to.deep.equal({
- ac: '300x250',
- ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- bif: 0.95,
- bs: 'sortable',
- s: initialConfig.options.siteId,
- cc: 'USD',
- c: 0.70,
- inr: true,
- _count: 1,
- _type: 'pbrw'
- });
- });
-
- it('should track late bidder timeouts', function() {
- events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT);
- events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED);
- events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END);
- clock.tick(DEFAULT_PBID_TIMEOUT);
- events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, TEST_DATA.BID_TIMEOUT);
-
- clock.tick(TIMEOUT_FOR_REGISTRY);
-
- expect(server.requests.length).to.equal(2);
- const pbid_req = JSON.parse(server.requests[0].requestBody);
- expect(pbid_req).to.have.own.property('pbid');
- const pbto_req = JSON.parse(server.requests[1].requestBody);
- expect(pbto_req).to.have.own.property('pbto');
- expect(pbto_req.pbto).to.deep.equal({
- ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e',
- s: initialConfig.options.siteId,
- ac: '300x250',
- bs: 'sortable',
- _type: 'pbto',
- _count: 1
- });
- });
-
- it('should track errors', function() {
- events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT);
- events.emit(CONSTANTS.EVENTS.BID_REQUESTED, {});
-
- clock.tick(TIMEOUT_FOR_REGISTRY);
-
- expect(server.requests.length).to.equal(1);
- const err_req = JSON.parse(server.requests[0].requestBody);
- expect(err_req).to.have.own.property('pber');
- expect(err_req.pber).to.include({
- args: '{}',
- s: initialConfig.options.siteId,
- _count: 1,
- ti: 'bidRequested',
- _type: 'pber'
- });
- expect(err_req.pber.msg).to.be.a('string');
- });
- });
-});
diff --git a/test/spec/modules/sortableBidAdapter_spec.js b/test/spec/modules/sortableBidAdapter_spec.js
deleted file mode 100644
index 7357fa77952..00000000000
--- a/test/spec/modules/sortableBidAdapter_spec.js
+++ /dev/null
@@ -1,547 +0,0 @@
-import { expect } from 'chai';
-import { spec } from 'modules/sortableBidAdapter.js';
-import { newBidder } from 'src/adapters/bidderFactory.js';
-import * as utils from 'src/utils.js';
-
-describe('sortableBidAdapter', function() {
- const adapter = newBidder(spec);
-
- describe('isBidRequestValid', function () {
- function makeBid() {
- return {
- 'bidder': 'sortable',
- 'params': {
- 'tagId': '403370',
- 'siteId': 'example.com',
- 'keywords': {
- 'key1': 'val1',
- 'key2': 'val2'
- }
- },
- 'adUnitCode': 'adunit-code',
- 'sizes': [
- [300, 250]
- ],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- };
- }
-
- it('should return true when required params found', function () {
- expect(spec.isBidRequestValid(makeBid())).to.equal(true);
- });
-
- it('should return false when tagId not passed correctly', function () {
- let bid = makeBid();
- delete bid.params.tagId;
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
-
- it('should return false when sizes not passed correctly', function () {
- let bid = makeBid();
- delete bid.sizes;
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
-
- it('should return false when sizes are wrong length', function () {
- let bid = makeBid();
- bid.sizes = [[300]];
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
-
- it('should return false when sizes are empty', function () {
- let bid = makeBid();
- bid.sizes = [];
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
-
- it('should return false when require params are not passed', function () {
- let bid = makeBid();
- bid.params = {};
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
-
- it('should return false when the keywords are invalid', function () {
- 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', function () {
- let bid = makeBid();
- bid.params.keywords = {};
- expect(spec.isBidRequestValid(bid)).to.equal(true);
- delete bid.params.keywords;
- expect(spec.isBidRequestValid(bid)).to.equal(true);
- });
-
- it('should return true with video media type', () => {
- const videoBid = {
- 'bidder': 'sortable',
- 'params': {
- 'tagId': '403370',
- 'siteId': 'example.com',
- },
- 'adUnitCode': 'adunit-code',
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'mediaTypes': {
- 'video': {
- }
- }
- };
- expect(spec.isBidRequestValid(videoBid)).to.equal(true);
- });
- });
-
- describe('buildRequests', function () {
- const bidRequests = [{
- 'bidder': 'sortable',
- 'params': {
- 'tagId': '403370',
- 'siteId': 'example.com',
- 'floor': 0.21,
- 'keywords': {
- 'key1': 'val1',
- 'key2': 'val2'
- }
- },
- 'ortb2Imp': {
- 'ext': {
- 'data': {
- 'pbadslot': 'abc/123'
- }
- }
- },
- 'sizes': [
- [300, 250]
- ],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }, {
- 'bidder': 'sortable',
- 'params': {
- 'tagId': '403371',
- 'siteId': 'example.com',
- 'floor': 0.21
- },
- 'sizes': [
- [300, 250]
- ],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'mediaTypes': {
- 'native': {
- 'body': {'required': true, 'sendId': true},
- 'clickUrl': {'required': true, 'sendId': true},
- 'cta': {'required': true, 'sendId': true},
- 'icon': {'required': true, 'sendId': true},
- 'image': {'required': true, 'sendId': true},
- 'sponsoredBy': {'required': true, 'sendId': true},
- 'title': {'required': true, 'sendId': true, 'len': 100}
- }
- }
- }];
-
- const request = spec.buildRequests(bidRequests, {refererInfo: { referer: 'http://example.com/page?param=val' }});
- const requestBody = JSON.parse(request.data);
-
- it('sends bid request to our endpoint via POST', function () {
- expect(request.method).to.equal('POST');
- });
-
- it('attaches source and version to endpoint URL as query params', function () {
- const ENDPOINT = `https://c.deployads.com/openrtb2/auction?src=$$REPO_AND_VERSION$$&host=example.com`;
- expect(request.url).to.equal(ENDPOINT);
- });
-
- it('sends screen dimensions', function () {
- expect(requestBody.site.device.w).to.equal(screen.width);
- expect(requestBody.site.device.h).to.equal(screen.height);
- });
-
- it('includes the ad size in the bid request', function () {
- expect(requestBody.imp[0].banner.format[0].w).to.equal(300);
- expect(requestBody.imp[0].banner.format[0].h).to.equal(250);
- });
-
- it('includes the params in the bid request', function () {
- 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].floor).to.equal(0.21);
- });
-
- it('includes pbadslot in the bid request', function () {
- expect(requestBody.imp[0].ext.gpid).to.equal('abc/123');
- });
-
- it('sets domain and href correctly', function () {
- expect(requestBody.site.domain).to.equal('example.com');
- expect(requestBody.site.page).to.equal('http://example.com/page?param=val');
- });
-
- it('should have the version in native object set for native bid', function() {
- expect(requestBody.imp[1].native.ver).to.equal('1');
- });
-
- it('should have the assets set for native bid', function() {
- const assets = JSON.parse(requestBody.imp[1].native.request).assets;
- expect(assets[0]).to.deep.equal({'title': {'len': 100}, 'required': 1, 'id': 0});
- expect(assets[1]).to.deep.equal({'img': {'type': 3, 'wmin': 1, 'hmin': 1}, 'required': 1, 'id': 1});
- expect(assets[2]).to.deep.equal({'img': {'type': 1, 'wmin': 1, 'hmin': 1}, 'required': 1, 'id': 2});
- expect(assets[3]).to.deep.equal({'data': {'type': 2}, 'required': 1, 'id': 3});
- expect(assets[4]).to.deep.equal({'data': {'type': 12}, 'required': 1, 'id': 4});
- expect(assets[5]).to.deep.equal({'data': {'type': 1}, 'required': 1, 'id': 5});
- });
-
- const videoBidRequests = [{
- 'bidder': 'sortable',
- 'params': {
- 'tagId': '403370',
- 'siteId': 'example.com',
- 'video': {
- 'minduration': 5,
- 'maxduration': 10,
- 'startdelay': 0
- }
- },
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- 'mediaTypes': {
- 'video': {
- 'context': 'instream',
- 'mimes': ['video/x-ms-wmv'],
- 'playerSize': [[400, 300]],
- 'api': [0],
- 'protocols': [2, 3],
- 'playbackmethod': [1]
- }
- }
- }];
-
- const videoRequest = spec.buildRequests(videoBidRequests, {refererInfo: { referer: 'http://localhost:9876/' }});
- const videoRequestBody = JSON.parse(videoRequest.data);
-
- it('should include video params', () => {
- const video = videoRequestBody.imp[0].video;
- expect(video.mimes).to.deep.equal(['video/x-ms-wmv']);
- expect(video.w).to.equal(400);
- expect(video.h).to.equal(300);
- expect(video.api).to.deep.equal([0]);
- expect(video.protocols).to.deep.equal([2, 3]);
- expect(video.playbackmethod).to.deep.equal([1]);
- expect(video.minduration).to.equal(5);
- expect(video.maxduration).to.equal(10);
- expect(video.startdelay).to.equal(0);
- });
-
- it('sets domain and href correctly', function () {
- expect(videoRequestBody.site.domain).to.equal('localhost');
- expect(videoRequestBody.site.page).to.equal('http://localhost:9876/');
- });
-
- const gdprBidRequests = [{
- 'bidder': 'sortable',
- 'params': {
- 'tagId': '403370',
- 'siteId': 'example.com',
- 'floor': 0.21,
- 'keywords': {}
- },
- 'sizes': [
- [300, 250]
- ],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }];
- const consentString = 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==';
-
- function getGdprRequestBody(gdprApplies, consentString) {
- const gdprRequest = spec.buildRequests(gdprBidRequests, {'gdprConsent': {
- 'gdprApplies': gdprApplies,
- 'consentString': consentString
- },
- refererInfo: {
- referer: 'http://localhost:9876/'
- }});
- return JSON.parse(gdprRequest.data);
- }
-
- it('should handle gdprApplies being present and true', function() {
- const gdprRequestBody = getGdprRequestBody(true, consentString);
- expect(gdprRequestBody.regs.ext.gdpr).to.equal(1);
- expect(gdprRequestBody.user.ext.consent).to.equal(consentString);
- })
-
- it('should handle gdprApplies being present and false', function() {
- const gdprRequestBody = getGdprRequestBody(false, consentString);
- expect(gdprRequestBody.regs.ext.gdpr).to.equal(0);
- expect(gdprRequestBody.user.ext.consent).to.equal(consentString);
- })
-
- it('should handle gdprApplies being undefined', function() {
- const gdprRequestBody = getGdprRequestBody(undefined, consentString);
- expect(gdprRequestBody.regs).to.deep.equal({ext: {}});
- expect(gdprRequestBody.user.ext.consent).to.equal(consentString);
- })
-
- it('should handle gdprConsent being undefined', function() {
- const gdprRequest = spec.buildRequests(gdprBidRequests, {refererInfo: { referer: 'http://localhost:9876/' }});
- const gdprRequestBody = JSON.parse(gdprRequest.data);
- expect(gdprRequestBody.regs).to.deep.equal({ext: {}});
- expect(gdprRequestBody.user.ext.consent).to.equal(undefined);
- })
-
- const eidsBidRequests = [{
- 'bidder': 'sortable',
- 'params': {
- 'tagId': '403370',
- 'siteId': 'example.com',
- 'floor': 0.21,
- 'keywords': {}
- },
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475'
- }];
-
- it('should not set user ids when none present', function() {
- const eidsRequest = spec.buildRequests(eidsBidRequests, {refererInfo: {
- referer: 'http://localhost:9876/'
- }});
- const eidsRequestBody = JSON.parse(eidsRequest.data);
-
- expect(eidsRequestBody.user.ext.eids).to.equal(undefined);
- })
-
- it('should set user ids when present', function() {
- eidsBidRequests[0].userId = { criteoId: 'sample-userid' };
- const eidsRequest = spec.buildRequests(eidsBidRequests, {refererInfo: {
- referer: 'http://localhost:9876/'
- }});
- const eidsRequestBody = JSON.parse(eidsRequest.data);
-
- expect(eidsRequestBody.user.ext.eids.length).to.equal(1);
- })
- });
-
- describe('interpretResponse', function () {
- function makeResponse() {
- return {
- body: {
- 'id': '5e5c23a5ba71e78',
- 'seatbid': [
- {
- 'bid': [
- {
- 'id': '6vmb3isptf',
- 'crid': 'sortablescreative',
- 'impid': '322add653672f68',
- 'price': 1.22,
- 'adm': '',
- 'attr': [5],
- 'h': 90,
- 'nurl': 'http://nurl',
- 'w': 728
- }
- ],
- 'seat': 'MOCK'
- }
- ],
- 'bidid': '5e5c23a5ba71e78'
- }
- };
- }
-
- function makeNativeResponse() {
- return {
- body: {
- 'id': '5e5c23a5ba71e77',
- 'seatbid': [
- {
- 'bid': [
- {
- 'id': '6vmb3isptf',
- 'crid': 'sortablescreative',
- 'impid': '322add653672f67',
- 'price': 1.55,
- 'adm': '{"native":{"link":{"clicktrackers":[],"url":"https://www.sortable.com/"},"assets":[{"title":{"text":"Ads With Sortable"},"id":1},{"img":{"w":790,"url":"https://path.to/image","h":294},"id":2},{"img":{"url":"https://path.to/icon"},"id":3},{"data":{"value":"Body here"},"id":4},{"data":{"value":"Learn More"},"id":5},{"data":{"value":"Sortable"},"id":6}],"imptrackers":[],"ver":1}}',
- 'ext': {'ad_format': 'native'},
- 'h': 90,
- 'nurl': 'http://nurl',
- 'w': 728
- }
- ],
- 'seat': 'MOCK'
- }
- ],
- 'bidid': '5e5c23a5ba71e77'
- }
- };
- }
-
- const expectedBid = {
- 'requestId': '322add653672f68',
- 'cpm': 1.22,
- 'width': 728,
- 'height': 90,
- 'creativeId': 'sortablescreative',
- 'dealId': null,
- 'currency': 'USD',
- 'netRevenue': true,
- 'mediaType': 'banner',
- 'meta': { 'advertiserDomains': [] },
- 'ttl': 60,
- 'ad': '

'
- };
-
- const expectedNativeBid = {
- 'requestId': '322add653672f67',
- 'cpm': 1.55,
- 'width': 728,
- 'height': 90,
- 'creativeId': 'sortablescreative',
- 'dealId': null,
- 'currency': 'USD',
- 'netRevenue': true,
- 'sortable': { 'ad_format': 'native' },
- 'mediaType': 'native',
- 'meta': { 'advertiserDomains': [] },
- 'ttl': 60,
- 'native': {
- 'clickUrl': 'https://www.sortable.com/',
- 'title': 'Ads With Sortable',
- 'image': {'url': 'https://path.to/image', 'height': 294, 'width': 790},
- 'icon': 'https://path.to/icon',
- 'body': 'Body here',
- 'cta': 'Learn More',
- 'sponsoredBy': 'Sortable'
- }
- };
-
- it('should get the correct bid response', function () {
- let result = spec.interpretResponse(makeResponse());
- expect(result.length).to.equal(1);
- expect(result[0]).to.deep.equal(expectedBid);
- });
-
- it('should handle a missing crid', function () {
- 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', function () {
- let noNurlResponse = makeResponse();
- delete noNurlResponse.body.seatbid[0].bid[0].nurl;
- let noNurlResult = Object.assign({}, expectedBid);
- noNurlResult.ad = '';
- let result = spec.interpretResponse(noNurlResponse);
- expect(result.length).to.equal(1);
- expect(result[0]).to.deep.equal(noNurlResult);
- });
-
- it('should handle a missing adm', function () {
- let noAdmResponse = makeResponse();
- delete noAdmResponse.body.seatbid[0].bid[0].adm;
- let noAdmResult = Object.assign({}, expectedBid);
- delete noAdmResult.ad;
- noAdmResult.adUrl = 'http://nurl';
- let result = spec.interpretResponse(noAdmResponse);
- expect(result.length).to.equal(1);
- expect(result[0]).to.deep.equal(noAdmResult);
- });
-
- it('handles empty bid response', function () {
- let response = {
- body: {
- 'id': '5e5c23a5ba71e78',
- 'seatbid': []
- }
- };
- let result = spec.interpretResponse(response);
- expect(result.length).to.equal(0);
- });
-
- it('should get the correct native bid response', function () {
- let result = spec.interpretResponse(makeNativeResponse());
- expect(result.length).to.equal(1);
- expect(result[0]).to.deep.equal(expectedNativeBid);
- });
-
- it('fail to parse invalid native bid response', function () {
- let response = makeNativeResponse();
- response.body.seatbid[0].bid[0].adm = '';
- let result = spec.interpretResponse(response);
- expect(result.length).to.equal(0);
- });
-
- it('should keep custom properties', () => {
- const customProperties = {test: 'a test message', param: {testParam: 1}};
- const expectedResult = Object.assign({}, expectedBid, {[spec.code]: customProperties});
- const response = makeResponse();
- response.body.seatbid[0].bid[0].ext = customProperties;
- const result = spec.interpretResponse(response);
- expect(result.length).to.equal(1);
- expect(result[0]).to.deep.equal(expectedResult);
- });
-
- it('should handle instream response', () => {
- const response = makeResponse();
- const bid = response.body.seatbid[0].bid[0];
- delete bid.nurl;
- bid.ext = {ad_format: 'instream'};
- const result = spec.interpretResponse(response)[0];
- expect(result.mediaType).to.equal('video');
- expect(result.vastXml).to.equal(bid.adm);
- });
-
- it('should return iframe syncs', () => {
- const syncResponse = {
- ext: {
- sync_dsps: [
- ['iframe', 'http://example-dsp/sync-iframe'],
- ['image', 'http://example-dsp/sync-image']
- ]
- }
- };
- expect(spec.getUserSyncs({iframeEnabled: true}, [{body: syncResponse}])).to.deep.equal([{
- type: 'iframe',
- url: 'http://example-dsp/sync-iframe'
- }]);
- });
-
- it('should return image syncs', () => {
- const syncResponse = {
- ext: {
- sync_dsps: [
- ['iframe', 'http://example-dsp/sync-iframe'],
- ['image', 'http://example-dsp/sync-image']
- ]
- }
- };
- expect(spec.getUserSyncs({pixelEnabled: true}, [{body: syncResponse}])).to.deep.equal([{
- type: 'image',
- url: 'http://example-dsp/sync-image'
- }]);
- });
- });
-});
diff --git a/test/spec/modules/sovrnAnalyticsAdapter_spec.js b/test/spec/modules/sovrnAnalyticsAdapter_spec.js
index d6795331417..8284bb54e9b 100644
--- a/test/spec/modules/sovrnAnalyticsAdapter_spec.js
+++ b/test/spec/modules/sovrnAnalyticsAdapter_spec.js
@@ -202,7 +202,8 @@ describe('Sovrn Analytics Adapter', function () {
events.emit(constants.EVENTS.BID_RESPONSE, {});
events.emit(constants.EVENTS.BID_WON, {});
- sinon.assert.callCount(sovrnAnalyticsAdapter.track, 5);
+ // 5 SovrnAnalytics events + 1 Clean.io event
+ sinon.assert.callCount(sovrnAnalyticsAdapter.track, 6);
});
it('should catch no events if no affiliate id', function () {
diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js
index c515f302c32..02a3d86b29a 100644
--- a/test/spec/modules/sovrnBidAdapter_spec.js
+++ b/test/spec/modules/sovrnBidAdapter_spec.js
@@ -21,7 +21,8 @@ const baseBidRequest = {
}
const baseBidderRequest = {
refererInfo: {
- referer: 'http://example.com/page.html',
+ page: 'http://example.com/page.html',
+ domain: 'example.com',
}
}
@@ -94,9 +95,9 @@ describe('sovrnBidAdapter', function() {
expect(impression.banner.h).to.equal(1)
})
- it('sets the proper video object', function() {
- const width = 640
- const height = 480
+ it('sets the proper video object with sizes defined', function() {
+ const width = 300
+ const height = 250
const mimes = ['video/mp4', 'application/javascript']
const protocols = [2, 5]
const minduration = 5
@@ -128,6 +129,42 @@ describe('sovrnBidAdapter', function() {
expect(impression.video.startdelay).to.equal(startdelay)
})
+ it('sets the proper video object wihtout sizes defined but video sizes defined', function() {
+ const width = 360
+ const height = 240
+ const mimes = ['video/mp4', 'application/javascript']
+ const protocols = [2, 5]
+ const minduration = 5
+ const maxduration = 60
+ const startdelay = 0
+ const modifiedBidRequest = baseBidRequest;
+ delete modifiedBidRequest.sizes;
+ const videoBidRequest = {
+ ...modifiedBidRequest,
+ mediaTypes: {
+ video: {
+ mimes,
+ protocols,
+ playerSize: [[width, height], [360, 240]],
+ minduration,
+ maxduration,
+ startdelay
+ }
+ }
+ }
+ const request = spec.buildRequests([videoBidRequest], baseBidderRequest)
+ const payload = JSON.parse(request.data)
+ const impression = payload.imp[0]
+
+ expect(impression.video.w).to.equal(width)
+ expect(impression.video.h).to.equal(height)
+ expect(impression.video.mimes).to.have.same.members(mimes)
+ expect(impression.video.protocols).to.have.same.members(protocols)
+ expect(impression.video.minduration).to.equal(minduration)
+ expect(impression.video.maxduration).to.equal(maxduration)
+ expect(impression.video.startdelay).to.equal(startdelay)
+ })
+
it('gets correct site info', function() {
expect(payload.site.page).to.equal('http://example.com/page.html')
expect(payload.site.domain).to.equal('example.com')
@@ -253,8 +290,6 @@ describe('sovrnBidAdapter', function() {
expect(secondEID.uids[0].id).to.equal('SOMESORTOFID')
expect(secondEID.uids[0].ext.rtiPartner).to.equal('TDID')
expect(secondEID.uids[0].atype).to.equal(1)
- expect(ext.tpid[0].source).to.equal('criteo.com')
- expect(ext.tpid[0].uid).to.equal('A_CRITEO_ID')
expect(ext.prebid_criteoid).to.equal('A_CRITEO_ID')
})
@@ -307,30 +342,17 @@ describe('sovrnBidAdapter', function() {
expect(impression.bidfloor).to.equal(2.00)
})
describe('First Party Data', function () {
- let sandbox
-
- beforeEach(function() {
- sandbox = sinon.sandbox.create()
- })
- afterEach(function() {
- sandbox.restore()
- })
it('should provide first party data if provided', function() {
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const cfg = {
- ortb2: {
- site: {
- keywords: 'test keyword'
- },
- user: {
- data: 'some user data'
- }
- }
+ const ortb2 = {
+ site: {
+ keywords: 'test keyword'
+ },
+ user: {
+ data: 'some user data'
}
- return utils.deepAccess(cfg, key)
- })
+ };
- const request = spec.buildRequests([baseBidRequest], baseBidderRequest)
+ const request = spec.buildRequests([baseBidRequest], {...baseBidderRequest, ortb2})
const { user, site } = JSON.parse(request.data)
expect(user.data).to.equal('some user data')
diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js
index d536976092b..90bd931d8ce 100644
--- a/test/spec/modules/spotxBidAdapter_spec.js
+++ b/test/spec/modules/spotxBidAdapter_spec.js
@@ -1,5 +1,6 @@
import {expect} from 'chai';
import {config} from 'src/config.js';
+import {loadExternalScript} from '../../../src/adloader';
import {spec, GOOGLE_CONSENT} from 'modules/spotxBidAdapter.js';
describe('the spotx adapter', function () {
@@ -18,14 +19,14 @@ describe('the spotx adapter', function () {
};
describe('isBidRequestValid', function() {
- var bid;
+ let bid;
beforeEach(function() {
bid = getValidBidObject();
});
it('should fail validation if the bid isn\'t defined or not an object', function() {
- var result = spec.isBidRequestValid();
+ let result = spec.isBidRequestValid();
expect(result).to.equal(false);
@@ -92,15 +93,19 @@ describe('the spotx adapter', function () {
});
describe('buildRequests', function() {
- var bid, bidRequestObj;
+ let bid, bidRequestObj;
beforeEach(function() {
bid = getValidBidObject();
- bidRequestObj = {refererInfo: {referer: 'prebid.js'}};
+ bidRequestObj = {
+ refererInfo: {
+ page: 'prebid.js'
+ }
+ };
});
it('should build a very basic request', function() {
- var request = spec.buildRequests([bid], bidRequestObj)[0];
+ let request = spec.buildRequests([bid], bidRequestObj)[0];
expect(request.method).to.equal('POST');
expect(request.url).to.equal('https://search.spotxchange.com/openrtb/2.3/dados/12345?src_sys=prebid');
expect(request.bidRequest).to.equal(bidRequestObj);
@@ -129,7 +134,7 @@ describe('the spotx adapter', function () {
});
it('should change request parameters based on options sent', function() {
- var request = spec.buildRequests([bid], bidRequestObj)[0];
+ let request = spec.buildRequests([bid], bidRequestObj)[0];
expect(request.data.imp.video.ext).to.deep.equal({
sdk_name: 'Prebid 1+',
versionOrtb: '2.3'
@@ -153,10 +158,22 @@ describe('the spotx adapter', function () {
position: 1
};
- bid.userId = {
- id5id: { uid: 'id5id_1' },
- tdid: 'tdid_1'
- };
+ bid.userIdAsEids = [{
+ source: 'adserver.org',
+ uids: [{id: 'tdid_1', atype: 1, ext: {rtiPartner: 'TDID'}}]
+ },
+ {
+ source: 'id5-sync.com',
+ uids: [{id: 'id5id_1', ext: {}}]
+ },
+ {
+ source: 'uidapi.com',
+ uids: [{
+ id: 'uid_1',
+ atype: 3
+ }]
+ }
+ ];
bid.crumbs = {
pubcid: 'pubcid_1'
@@ -200,6 +217,15 @@ describe('the spotx adapter', function () {
expect(request.data.user.ext).to.deep.equal({
consented_providers_settings: GOOGLE_CONSENT,
eids: [{
+ source: 'adserver.org',
+ uids: [{
+ id: 'tdid_1',
+ atype: 1,
+ ext: {
+ rtiPartner: 'TDID'
+ }
+ }]
+ }, {
source: 'id5-sync.com',
uids: [{
id: 'id5id_1',
@@ -207,16 +233,17 @@ describe('the spotx adapter', function () {
}]
},
{
- source: 'adserver.org',
+ source: 'uidapi.com',
uids: [{
- id: 'tdid_1',
+ id: 'uid_1',
+ atype: 3,
ext: {
- rtiPartner: 'TDID'
+ rtiPartner: 'UID2'
}
}]
}],
fpc: 'pubcid_1'
- })
+ });
expect(request.data.source).to.deep.equal({
ext: {
@@ -235,7 +262,7 @@ describe('the spotx adapter', function () {
});
it('should process premarket bids', function() {
- var request;
+ let request;
sinon.stub(Date, 'now').returns(1000);
bid.params.pre_market_bids = [{
@@ -273,7 +300,7 @@ describe('the spotx adapter', function () {
});
it('should pass GDPR params', function() {
- var request;
+ let request;
bidRequestObj.gdprConsent = {
consentString: 'consent123',
@@ -287,7 +314,7 @@ describe('the spotx adapter', function () {
});
it('should pass CCPA us_privacy string', function() {
- var request;
+ let request;
bidRequestObj.uspConsent = '1YYY'
@@ -296,7 +323,7 @@ describe('the spotx adapter', function () {
});
it('should pass both GDPR params and CCPA us_privacy', function() {
- var request;
+ let request;
bidRequestObj.gdprConsent = {
consentString: 'consent123',
@@ -311,7 +338,7 @@ describe('the spotx adapter', function () {
});
it('should pass min and max duration params', function() {
- var request;
+ let request;
bid.params.min_duration = 3
bid.params.max_duration = 15
@@ -323,7 +350,7 @@ describe('the spotx adapter', function () {
});
it('should pass placement_type and position params', function() {
- var request;
+ let request;
bid.params.placement_type = 2
bid.params.position = 5
@@ -335,11 +362,11 @@ describe('the spotx adapter', function () {
});
it('should pass page param and override refererInfo.referer', function() {
- var request;
+ let request;
bid.params.page = 'https://example.com';
- var origGetConfig = config.getConfig;
+ let origGetConfig = config.getConfig;
sinon.stub(config, 'getConfig').callsFake(function (key) {
if (key === 'pageUrl') {
return 'https://www.spotx.tv';
@@ -353,25 +380,8 @@ describe('the spotx adapter', function () {
config.getConfig.restore();
});
- it('should use pageUrl from config if page param is not passed', function() {
- var request;
-
- var origGetConfig = config.getConfig;
- sinon.stub(config, 'getConfig').callsFake(function (key) {
- if (key === 'pageUrl') {
- return 'https://www.spotx.tv';
- }
- return origGetConfig.apply(config, arguments);
- });
-
- request = spec.buildRequests([bid], bidRequestObj)[0];
-
- expect(request.data.site.page).to.equal('https://www.spotx.tv');
- config.getConfig.restore();
- });
-
- it('should use refererInfo.referer if no page or pageUrl are passed', function() {
- var request;
+ it('should use refererInfo.referer if no page is passed', function() {
+ let request;
request = spec.buildRequests([bid], bidRequestObj)[0];
@@ -379,9 +389,9 @@ describe('the spotx adapter', function () {
});
it('should set ext.wrap_response to 0 when cache url is set and ignoreBidderCacheKey is true', function() {
- var request;
+ let request;
- var origGetConfig = config.getConfig;
+ let origGetConfig = config.getConfig;
sinon.stub(config, 'getConfig').callsFake(function (key) {
if (key === 'cache') {
return {
@@ -405,7 +415,7 @@ describe('the spotx adapter', function () {
});
it('should pass price floor in USD from the floors module if available', function () {
- var request;
+ let request;
bid.getFloor = function () {
return { currency: 'USD', floor: 3 };
@@ -419,7 +429,7 @@ describe('the spotx adapter', function () {
});
it('should not pass price floor if price floors module gives a non-USD currency', function () {
- var request;
+ let request;
bid.getFloor = function () {
return { currency: 'EUR', floor: 3 };
@@ -431,7 +441,7 @@ describe('the spotx adapter', function () {
});
it('if floors module is not available, should pass price floor from price_floor param if available', function () {
- var request;
+ let request;
bid.params.price_floor = 2;
@@ -442,7 +452,7 @@ describe('the spotx adapter', function () {
});
describe('interpretResponse', function() {
- var serverResponse, bidderRequestObj;
+ let serverResponse, bidderRequestObj;
beforeEach(function() {
bidderRequestObj = {
@@ -455,6 +465,7 @@ describe('the spotx adapter', function () {
},
bidId: 123,
params: {
+ ad_unit: 'outstream',
player_width: 400,
player_height: 300,
content_page_url: 'prebid.js',
@@ -515,7 +526,7 @@ describe('the spotx adapter', function () {
});
it('should return an array of bid responses', function() {
- var responses = spec.interpretResponse(serverResponse, bidderRequestObj);
+ let responses = spec.interpretResponse(serverResponse, bidderRequestObj);
expect(responses).to.be.an('array').with.length(2);
expect(responses[0].cache_key).to.equal('cache123');
expect(responses[0].channel_id).to.equal(12345);
@@ -546,12 +557,30 @@ describe('the spotx adapter', function () {
expect(responses[1].videoCacheKey).to.equal('cache124');
expect(responses[1].width).to.equal(200);
});
+
+ it('should set the renderer attached to the bid to render immediately', function () {
+ var renderer = spec.interpretResponse(serverResponse, bidderRequestObj)[0].renderer,
+ hasRun = false;
+ expect(renderer._render).to.be.a('function');
+ renderer._render = () => {
+ hasRun = true;
+ }
+ renderer.render();
+ expect(hasRun).to.equal(true);
+ });
});
describe('outstreamRender', function() {
- var serverResponse, bidderRequestObj;
+ let serverResponse, bidderRequestObj;
beforeEach(function() {
+ sinon.stub(window.document, 'getElementById').returns({
+ clientWidth: 200,
+ appendChild: sinon.stub().callsFake(function(script) {})
+ });
+ sinon.stub(window.document, 'createElement').returns({
+ setAttribute: function () {}
+ });
bidderRequestObj = {
bidRequest: {
bids: [{
@@ -601,99 +630,76 @@ describe('the spotx adapter', function () {
}
};
});
+ afterEach(function () {
+ window.document.getElementById.restore();
+ window.document.createElement.restore();
+ });
it('should attempt to insert the EASI script', function() {
- var scriptTag;
+ window.document.getElementById.restore();
sinon.stub(window.document, 'getElementById').returns({
- appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; })
+ appendChild: sinon.stub().callsFake(function(script) {}),
});
- var responses = spec.interpretResponse(serverResponse, bidderRequestObj);
+ let responses = spec.interpretResponse(serverResponse, bidderRequestObj);
+ let attrs;
responses[0].renderer.render(responses[0]);
-
- expect(scriptTag.getAttribute('type')).to.equal('text/javascript');
- expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js');
- expect(scriptTag.getAttribute('data-spotx_channel_id')).to.equal('12345');
- expect(scriptTag.getAttribute('data-spotx_vast_url')).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123');
- expect(scriptTag.getAttribute('data-spotx_ad_unit')).to.equal('incontent');
- expect(scriptTag.getAttribute('data-spotx_collapse')).to.equal('0');
- expect(scriptTag.getAttribute('data-spotx_autoplay')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_blocked_autoplay_override_mode')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_video_slot_can_autoplay')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_digitrust_opt_out')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('400');
- expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('300');
- expect(scriptTag.getAttribute('data-spotx_ad_mute')).to.equal('1');
- window.document.getElementById.restore();
+ expect(loadExternalScript.called).to.be.true;
+ attrs = valuesToString(loadExternalScript.args[0][4]);
+
+ expect(attrs['data-spotx_channel_id']).to.equal('12345');
+ expect(attrs['data-spotx_vast_url']).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123');
+ expect(attrs['data-spotx_ad_unit']).to.equal('incontent');
+ expect(attrs['data-spotx_collapse']).to.equal('0');
+ expect(attrs['data-spotx_autoplay']).to.equal('1');
+ expect(attrs['data-spotx_blocked_autoplay_override_mode']).to.equal('1');
+ expect(attrs['data-spotx_video_slot_can_autoplay']).to.equal('1');
+ expect(attrs['data-spotx_digitrust_opt_out']).to.equal('1');
+ expect(attrs['data-spotx_content_width']).to.equal('400');
+ expect(attrs['data-spotx_content_height']).to.equal('300');
+ expect(attrs['data-spotx_ad_mute']).to.equal('1');
});
it('should append into an iframe', function() {
- var scriptTag;
+ bidderRequestObj.bidRequest.bids[0].params.outstream_options.in_iframe = 'iframeId';
+ window.document.getElementById.restore();
sinon.stub(window.document, 'getElementById').returns({
nodeName: 'IFRAME',
- contentDocument: {
- body: {
- appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; })
- }
- }
+ clientWidth: 200,
+ appendChild: sinon.stub().callsFake(function(script) {}),
+ contentDocument: {nodeName: 'IFRAME'}
});
- bidderRequestObj.bidRequest.bids[0].params.outstream_options.in_iframe = 'iframeId';
-
- var responses = spec.interpretResponse(serverResponse, bidderRequestObj);
-
+ let responses = spec.interpretResponse(serverResponse, bidderRequestObj);
responses[0].renderer.render(responses[0]);
-
- expect(scriptTag.getAttribute('type')).to.equal('text/javascript');
- expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js');
- expect(scriptTag.getAttribute('data-spotx_channel_id')).to.equal('12345');
- expect(scriptTag.getAttribute('data-spotx_vast_url')).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123');
- expect(scriptTag.getAttribute('data-spotx_ad_unit')).to.equal('incontent');
- expect(scriptTag.getAttribute('data-spotx_collapse')).to.equal('0');
- expect(scriptTag.getAttribute('data-spotx_autoplay')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_blocked_autoplay_override_mode')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_video_slot_can_autoplay')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_digitrust_opt_out')).to.equal('1');
- expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('400');
- expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('300');
- window.document.getElementById.restore();
+ expect(loadExternalScript.called).to.be.true;
+ expect(loadExternalScript.args[0][3].nodeName).to.equal('IFRAME');
});
it('should adjust width and height to match slot clientWidth if playersize_auto_adapt is used', function() {
- var scriptTag;
- sinon.stub(window.document, 'getElementById').returns({
- clientWidth: 200,
- appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; })
- });
- var responses = spec.interpretResponse(serverResponse, bidderRequestObj);
+ let responses = spec.interpretResponse(serverResponse, bidderRequestObj);
responses[0].renderer.render(responses[0]);
-
- expect(scriptTag.getAttribute('type')).to.equal('text/javascript');
- expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js');
- expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('200');
- expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('150');
- window.document.getElementById.restore();
+ expect(loadExternalScript.args[0][4]['data-spotx_content_width']).to.equal('200');
+ expect(loadExternalScript.args[0][4]['data-spotx_content_height']).to.equal('150');
});
it('should use a default 4/3 ratio if playersize_auto_adapt is used and response does not contain width or height', function() {
delete serverResponse.body.seatbid[0].bid[0].w;
delete serverResponse.body.seatbid[0].bid[0].h;
-
- var scriptTag;
- sinon.stub(window.document, 'getElementById').returns({
- clientWidth: 200,
- appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; })
- });
- var responses = spec.interpretResponse(serverResponse, bidderRequestObj);
+ let responses = spec.interpretResponse(serverResponse, bidderRequestObj);
responses[0].renderer.render(responses[0]);
-
- expect(scriptTag.getAttribute('type')).to.equal('text/javascript');
- expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js');
- expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('200');
- expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('150');
- window.document.getElementById.restore();
+ expect(loadExternalScript.args[0][4]['data-spotx_content_width']).to.equal('200');
+ expect(loadExternalScript.args[0][4]['data-spotx_content_height']).to.equal('150');
});
});
});
+
+function valuesToString(obj) {
+ let newObj = {};
+ for (let prop in obj) {
+ newObj[prop] = '' + obj[prop];
+ }
+ return newObj;
+}
diff --git a/test/spec/modules/sspBCBidAdapter_spec.js b/test/spec/modules/sspBCBidAdapter_spec.js
index 257d6815709..d182b9db24c 100644
--- a/test/spec/modules/sspBCBidAdapter_spec.js
+++ b/test/spec/modules/sspBCBidAdapter_spec.js
@@ -209,7 +209,8 @@ describe('SSPBC adapter', function () {
gdprConsent,
refererInfo: {
reachedTop: true,
- referer: 'https://test.site.pl/',
+ page: 'https://test.site.pl/',
+ domain: 'test.site.pl',
stack: ['https://test.site.pl/'],
}
};
@@ -221,7 +222,8 @@ describe('SSPBC adapter', function () {
gdprConsent,
refererInfo: {
reachedTop: true,
- referer: 'https://test.site.pl/',
+ page: 'https://test.site.pl/',
+ domain: 'test.site.pl',
stack: ['https://test.site.pl/'],
}
};
@@ -233,7 +235,8 @@ describe('SSPBC adapter', function () {
gdprConsent,
refererInfo: {
reachedTop: true,
- referer: 'https://test.site.pl/',
+ page: 'https://test.site.pl/',
+ domain: 'test.site.pl',
stack: ['https://test.site.pl/'],
}
};
@@ -245,7 +248,8 @@ describe('SSPBC adapter', function () {
gdprConsent,
refererInfo: {
reachedTop: true,
- referer: 'https://test.site.pl/',
+ page: 'https://test.site.pl/',
+ domain: 'test.site.pl',
stack: ['https://test.site.pl/'],
}
};
@@ -257,7 +261,8 @@ describe('SSPBC adapter', function () {
gdprConsent,
refererInfo: {
reachedTop: true,
- referer: 'https://test.site.pl/',
+ page: 'https://test.site.pl/',
+ domain: 'test.site.pl',
stack: ['https://test.site.pl/'],
}
};
@@ -269,7 +274,8 @@ describe('SSPBC adapter', function () {
gdprConsent,
refererInfo: {
reachedTop: true,
- referer: 'https://test.site.pl/',
+ page: 'https://test.site.pl/',
+ domain: 'test.site.pl',
stack: ['https://test.site.pl/'],
}
};
@@ -280,7 +286,8 @@ describe('SSPBC adapter', function () {
bids: bids_test,
refererInfo: {
reachedTop: true,
- referer: 'https://test.site.pl/',
+ page: 'https://test.site.pl/',
+ domain: 'test.site.pl',
stack: ['https://test.site.pl/'],
}
};
@@ -511,7 +518,7 @@ describe('SSPBC adapter', function () {
});
it('should send page url from refererInfo', function () {
- expect(payload.site.page).to.equal(bidRequest.refererInfo.referer);
+ expect(payload.site.page).to.equal(bidRequest.refererInfo.page);
});
it('should send gdpr data', function () {
@@ -671,8 +678,8 @@ describe('SSPBC adapter', function () {
});
it('should send no syncs, if frame sync is not allowed', function () {
- expect(syncResultImage).to.have.length(0); ;
- expect(syncResultNone).to.have.length(0); ;
+ expect(syncResultImage).to.have.length(0);
+ expect(syncResultNone).to.have.length(0);
});
});
diff --git a/test/spec/modules/stroeerCoreBidAdapter_spec.js b/test/spec/modules/stroeerCoreBidAdapter_spec.js
index e723523de31..5b43b78280b 100644
--- a/test/spec/modules/stroeerCoreBidAdapter_spec.js
+++ b/test/spec/modules/stroeerCoreBidAdapter_spec.js
@@ -58,6 +58,10 @@ describe('stroeerCore bid adapter', function () {
bidderCode: 'stroeerCore',
timeout: 5000,
auctionStart: 10000,
+ refererInfo: {
+ page: 'https://www.example.com/monkey/index.html',
+ ref: 'https://www.example.com/?search=monkey'
+ },
bids: [{
bidId: 'bid1',
bidder: 'stroeerCore',
@@ -106,7 +110,7 @@ describe('stroeerCore bid adapter', function () {
});
const createWindow = (href, params = {}) => {
- let {parent, referrer, top, frameElement, placementElements = []} = params;
+ let {parent, top, frameElement, placementElements = []} = params;
const protocol = (href.indexOf('https') === 0) ? 'https:' : 'http:';
const win = {
@@ -123,7 +127,6 @@ describe('stroeerCore bid adapter', function () {
}
}
},
- referrer,
getElementById: id => find(placementElements, el => el.id === id)
}
};
@@ -166,7 +169,7 @@ describe('stroeerCore bid adapter', function () {
}
function setupNestedWindows(sandBox, placementElements = [createElement('div-1', 17), createElement('div-2', 54)]) {
- const topWin = createWindow('http://www.abc.org/', {referrer: 'http://www.google.com/?query=monkey'});
+ const topWin = createWindow('http://www.abc.org/');
topWin.innerHeight = 800;
const midWin = createWindow('http://www.abc.org/', {parent: topWin, top: topWin, frameElement: createElement()});
@@ -307,9 +310,10 @@ describe('stroeerCore bid adapter', function () {
const expectedJsonPayload = {
'id': AUCTION_ID,
'timeout': expectedTimeout,
- 'ref': topWin.document.referrer,
+ 'ref': 'https://www.example.com/?search=monkey',
'mpa': true,
'ssl': false,
+ 'url': 'https://www.example.com/monkey/index.html',
'bids': [{
'sid': 'NDA=', 'bid': 'bid1', 'siz': [[300, 600], [160, 60]], 'viz': true
}, {
@@ -399,6 +403,30 @@ describe('stroeerCore bid adapter', function () {
assert.lengthOf(serverRequestInfo.data.bids, 2);
assert.notProperty(serverRequestInfo, 'uids');
});
+
+ it('should add schain if available', () => {
+ const schain = Object.freeze({
+ ver: '1.0',
+ complete: 1,
+ 'nodes': [
+ {
+ asi: 'exchange1.com',
+ sid: 'ABC',
+ hp: 1,
+ rid: 'bid-request-1',
+ name: 'publisher',
+ domain: 'publisher.com'
+ }
+ ]
+ });
+
+ const bidReq = buildBidderRequest();
+ bidReq.bids.forEach(bid => bid.schain = schain);
+
+ const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq);
+
+ assert.deepEqual(serverRequestInfo.data.schain, schain);
+ });
});
});
});
diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js
index 2779658ff6a..0773d29789d 100644
--- a/test/spec/modules/synacormediaBidAdapter_spec.js
+++ b/test/spec/modules/synacormediaBidAdapter_spec.js
@@ -183,6 +183,14 @@ describe('synacormediaBidAdapter ', function () {
}
};
+ let bidderRequestWithTimeout = {
+ auctionId: 'xyz123',
+ refererInfo: {
+ referer: 'https://test.com/foo/bar'
+ },
+ timeout: 3000
+ };
+
let bidderRequestWithCCPA = {
auctionId: 'xyz123',
refererInfo: {
@@ -295,6 +303,42 @@ describe('synacormediaBidAdapter ', function () {
expect(reqVideo.data.imp).to.eql([expectedDataVideo1]);
});
+ it('should return no tmax', function () {
+ let req = spec.buildRequests([validBidRequest], bidderRequest);
+ expect(req.data).to.not.have.property('tmax');
+ });
+
+ it('should return tmax equal to callback timeout', function () {
+ let req = spec.buildRequests([validBidRequest], bidderRequestWithTimeout);
+ expect(req.data.tmax).to.eql(bidderRequestWithTimeout.timeout);
+ });
+
+ it('should return tmax equal to smaller global timeout', function () {
+ let sandbox = sinon.sandbox.create();
+ sandbox.stub(config, 'getConfig').callsFake(key => {
+ const config = {
+ 'bidderTimeout': bidderRequestWithTimeout.timeout - 100
+ };
+ return config[key];
+ });
+ let req = spec.buildRequests([validBidRequest], bidderRequestWithTimeout);
+ sandbox.restore();
+ expect(req.data.tmax).to.eql(bidderRequestWithTimeout.timeout - 100);
+ });
+
+ it('should return tmax equal to smaller callback timeout', function () {
+ let sandbox = sinon.sandbox.create();
+ sandbox.stub(config, 'getConfig').callsFake(key => {
+ const config = {
+ 'bidderTimeout': bidderRequestWithTimeout.timeout + 100
+ };
+ return config[key];
+ });
+ let req = spec.buildRequests([validBidRequest], bidderRequestWithTimeout);
+ sandbox.restore();
+ expect(req.data.tmax).to.eql(bidderRequestWithTimeout.timeout);
+ });
+
it('should return multiple bids when multiple valid requests with the same seatId are used', function () {
let secondBidRequest = {
bidId: 'foobar',
diff --git a/test/spec/modules/taboolaBidAdapter_spec.js b/test/spec/modules/taboolaBidAdapter_spec.js
index 1c4f0fa4c32..5899b03a26d 100644
--- a/test/spec/modules/taboolaBidAdapter_spec.js
+++ b/test/spec/modules/taboolaBidAdapter_spec.js
@@ -89,6 +89,45 @@ describe('Taboola Adapter', function () {
}
expect(spec.isBidRequestValid(bid)).to.equal(true)
})
+
+ it('should succeed when url is null', function () {
+ const bid = {
+ bidder: 'taboola',
+ params: {
+ publisherId: 'publisherId',
+ tagId: 'below the article',
+ endpointUrl: null
+ },
+ ...displayBidRequestParams
+ }
+ expect(spec.isBidRequestValid(bid)).to.equal(true)
+ })
+
+ it('should succeed when url is empty string', function () {
+ const bid = {
+ bidder: 'taboola',
+ params: {
+ publisherId: 'publisherId',
+ tagId: 'below the article',
+ endpointUrl: ''
+ },
+ ...displayBidRequestParams
+ }
+ expect(spec.isBidRequestValid(bid)).to.equal(true)
+ })
+
+ it('should succeed when url is filled', function () {
+ const bid = {
+ bidder: 'taboola',
+ params: {
+ publisherId: 'publisherId',
+ tagId: 'below the article',
+ endpointUrl: 'https://example.com'
+ },
+ ...displayBidRequestParams
+ }
+ expect(spec.isBidRequestValid(bid)).to.equal(true)
+ })
})
describe('buildRequests', function () {
@@ -99,8 +138,9 @@ describe('Taboola Adapter', function () {
const commonBidderRequest = {
refererInfo: {
- referer: 'https://example.com/ref',
- canonicalUrl: 'https://example.com/'
+ page: 'https://example.com/ref',
+ ref: 'https://ref',
+ domain: 'example.com',
}
}
@@ -126,9 +166,9 @@ describe('Taboola Adapter', function () {
'site': {
'id': commonBidRequest.params.publisherId,
'name': commonBidRequest.params.publisherId,
- 'domain': window.location.host,
- 'page': commonBidderRequest.refererInfo.canonicalUrl,
- 'ref': commonBidderRequest.refererInfo.referer,
+ 'domain': commonBidderRequest.refererInfo.domain,
+ 'page': commonBidderRequest.refererInfo.page,
+ 'ref': commonBidderRequest.refererInfo.ref,
'publisher': {'id': commonBidRequest.params.publisherId},
'content': {'language': navigator.language}
},
@@ -147,6 +187,44 @@ describe('Taboola Adapter', function () {
expect(res.url).to.equal(`${END_POINT_URL}/${commonBidRequest.params.publisherId}`);
expect(res.data).to.deep.equal(JSON.stringify(expectedData));
+ });
+
+ it('should fill the url when it is passed', function () {
+ const commonBidRequestWithUrl = {
+ bidder: 'taboola',
+ params: {
+ publisherId: 'publisherId',
+ tagId: 'placement name',
+ endpointUrl: 'https://example.com'
+ },
+ bidId: 'aa43860a-4644-442a-b5e0-93f268cs4d19',
+ auctionId: '65746dca-26f3-4186-be13-dfa63469b1b7',
+ }
+ let defaultBidRequestWithUrl = {
+ ...commonBidRequestWithUrl,
+ ...displayBidRequestParams,
+ }
+ const res = spec.buildRequests([defaultBidRequestWithUrl], commonBidderRequest);
+ expect(res.url).to.equal(`${commonBidRequestWithUrl.params.endpointUrl}/${commonBidRequest.params.publisherId}`);
+ })
+
+ it('should fill default url when url param is empty string', function () {
+ const commonBidRequestWithUrl = {
+ bidder: 'taboola',
+ params: {
+ publisherId: 'publisherId',
+ tagId: 'placement name',
+ endpointUrl: ''
+ },
+ bidId: 'aa43860a-4644-442a-b5e0-93f268cs4d19',
+ auctionId: '65746dca-26f3-4186-be13-dfa63469b1b7',
+ }
+ let defaultBidRequestWithUrl = {
+ ...commonBidRequestWithUrl,
+ ...displayBidRequestParams,
+ }
+ const res = spec.buildRequests([defaultBidRequestWithUrl], commonBidderRequest);
+ expect(res.url).to.equal(`${END_POINT_URL}/${commonBidRequestWithUrl.params.publisherId}`);
})
it('should pass optional parameters in request', function () {
@@ -310,6 +388,7 @@ describe('Taboola Adapter', function () {
'crid': '278195503434041083381',
'w': 300,
'h': 250,
+ 'exp': 60,
'lurl': 'http://us-trc.taboola.com/sample'
}
],
@@ -369,7 +448,7 @@ describe('Taboola Adapter', function () {
requestId: request.bids[0].bidId,
cpm: bid.price,
creativeId: bid.crid,
- ttl: 360,
+ ttl: 60,
netRevenue: false,
currency: serverResponse.body.cur,
mediaType: 'banner',
@@ -385,6 +464,31 @@ describe('Taboola Adapter', function () {
const res = spec.interpretResponse(serverResponse, request)
expect(res).to.deep.equal(expectedRes)
});
+
+ it('should set the correct ttl form the response', function () {
+ // set exp-ttl to be 125
+ const [bid] = serverResponse.body.seatbid[0].bid;
+ serverResponse.body.seatbid[0].bid[0].exp = 125;
+ const expectedRes = [
+ {
+ requestId: request.bids[0].bidId,
+ cpm: bid.price,
+ creativeId: bid.crid,
+ ttl: 125,
+ netRevenue: false,
+ currency: serverResponse.body.cur,
+ mediaType: 'banner',
+ ad: bid.adm,
+ width: bid.w,
+ height: bid.h,
+ meta: {
+ 'advertiserDomains': bid.adomain
+ },
+ }
+ ];
+ const res = spec.interpretResponse(serverResponse, request);
+ expect(res).to.deep.equal(expectedRes);
+ });
})
describe('userData', function () {
@@ -393,62 +497,36 @@ describe('Taboola Adapter', function () {
describe('internal functions', function () {
describe('getPageUrl', function () {
- let origPageUrl;
const bidderRequest = {
refererInfo: {
- canonicalUrl: 'http://canonical.url'
+ page: 'http://canonical.url'
}
};
- beforeEach(function () {
- // remember original pageUrl in config
- origPageUrl = config.getConfig('pageUrl');
-
- // unset pageUrl in config
- config.setConfig({pageUrl: null});
- });
-
- afterEach(function () {
- // set original pageUrl to config
- config.setConfig({pageUrl: origPageUrl});
- });
-
it('should handle empty or missing data', function () {
- expect(internal.getPageUrl(undefined)).to.equal(utils.getWindowTop().location.href);
- expect(internal.getPageUrl('')).to.equal(utils.getWindowTop().location.href);
+ expect(internal.getPageUrl(undefined)).to.equal(utils.getWindowSelf().location.href);
+ expect(internal.getPageUrl('')).to.equal(utils.getWindowSelf().location.href);
});
- it('should use "pageUrl" from config', function () {
- config.setConfig({pageUrl: 'http://page.url'});
-
- expect(internal.getPageUrl(undefined)).to.equal(config.getConfig('pageUrl'));
- });
-
- it('should use bidderRequest.refererInfo.canonicalUrl', function () {
- expect(internal.getPageUrl(bidderRequest.refererInfo)).to.equal(bidderRequest.refererInfo.canonicalUrl);
- });
-
- it('should prefer bidderRequest.refererInfo.canonicalUrl over "pageUrl" from config', () => {
- config.setConfig({pageUrl: 'https://page.url'});
-
- expect(internal.getPageUrl(bidderRequest.refererInfo)).to.equal(bidderRequest.refererInfo.canonicalUrl);
+ it('should use bidderRequest.refererInfo.page', function () {
+ expect(internal.getPageUrl(bidderRequest.refererInfo)).to.equal(bidderRequest.refererInfo.page);
});
});
describe('getReferrer', function () {
it('should handle empty or missing data', function () {
- expect(internal.getReferrer(undefined)).to.equal(utils.getWindowTop().document.referrer);
- expect(internal.getReferrer('')).to.equal(utils.getWindowTop().document.referrer);
+ expect(internal.getReferrer(undefined)).to.equal(utils.getWindowSelf().document.referrer);
+ expect(internal.getReferrer('')).to.equal(utils.getWindowSelf().document.referrer);
});
- it('should use bidderRequest.refererInfo.referer', () => {
+ it('should use bidderRequest.refererInfo.ref', () => {
const bidderRequest = {
refererInfo: {
- referer: 'foobar'
+ ref: 'foobar'
}
};
- expect(internal.getReferrer(bidderRequest.refererInfo)).to.equal(bidderRequest.refererInfo.referer);
+ expect(internal.getReferrer(bidderRequest.refererInfo)).to.equal(bidderRequest.refererInfo.ref);
});
});
})
diff --git a/test/spec/modules/tappxBidAdapter_spec.js b/test/spec/modules/tappxBidAdapter_spec.js
index 8866670df77..58a62fb2869 100644
--- a/test/spec/modules/tappxBidAdapter_spec.js
+++ b/test/spec/modules/tappxBidAdapter_spec.js
@@ -17,14 +17,16 @@ const c_BIDREQUEST = {
crumbs: {
pubcid: 'df2144f7-673f-4440-83f5-cd4a73642d99'
},
- fpd: {
- context: {
- adServer: {
- name: 'gam',
- adSlot: '/19968336/header-bid-tag-0'
- },
- pbAdSlot: '/19968336/header-bid-tag-0',
- },
+ ortb2Imp: {
+ ext: {
+ data: {
+ adserver: {
+ name: 'gam',
+ adslot: '/19968336/header-bid-tag-0'
+ },
+ pbadslot: '/19968336/header-bid-tag-0',
+ }
+ }
},
mediaTypes: {
banner: {
@@ -121,7 +123,7 @@ const c_SERVERRESPONSE_V = {
const c_CONSENTSTRING = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
const c_VALIDBIDREQUESTS = [{'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com\/rtb\/v2\/', 'tappxkey': 'pub-1234-android-1234', 'endpoint': 'ZZ1234PBJS', 'bidfloor': 0.005, 'test': 1}, 'userId': {'haloId': '0000x179MZAzMqUWsFonu7Drm3eDDBMYtj5SPoWQnl89Upk3WTlCvEnKI9SshX0p6eFJ7otPYix179MZAzMqUWsFonu7Drm3eDDBMYtj5SPoWQnl89Upk3WTlCvEnKI9SshX0p6e', 'id5id': {'uid': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_rEXbz6UYtYEJelYrDaZOLkh8WcF9J0ZHmEHFKZEBlLXsgP6xqXU3BCj4Ay0Z6fw_jSOaHxMHwd-voRHqFA4Q9NwAxFcVLyPWnNGZ9VbcSAPos1wupq7Xu3MIm-Bw_0vxjhZdWNy4chM9x3i', 'ext': {'linkType': 0}}, 'intentIqId': 'GIF89a\u0000\u0000\u0000\u0000�\u0000\u0000���\u0000\u0000\u0000?�\u0000\u0000\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000A\u0000\u0000;', 'lotamePanoramaId': 'xTtLUY7GwqX2MMqSHo9RQ2YUOIBFhlASOR43I9KjvgtcrxIys3RxME96M02LTjWR', 'parrableId': {'eid': '02.YoqC9lWZh8.C8QTSiJTNgI6Pp0KCM5zZgEgwVMSsVP5W51X8cmiUHQESq9WRKB4nreqZJwsWIcNKlORhG4u25Wm6lmDOBmQ0B8hv0KP6uVQ97aouuH52zaz2ctVQTORUKkErPRPcaCJ7dKFcrNoF2i6WOR0S5Nk'}, 'pubcid': 'b1254-152f-12F5-5698-dI1eljK6C7WA', 'pubProvidedId': [{'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}]}, 'userIdAsEids': [{'source': 'audigent.com', 'uids': [{'id': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'atype': 1}]}, {'source': 'id5-sync.com', 'uids': [{'id': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'atype': 1, 'ext': {'linkType': 0}}]}], 'ortb2Imp': {'ext': {'data': {'adserver': {'name': 'gam', 'adslot': '/19968336/header-bid-tag-0'}, 'pbadslot': '/19968336/header-bid-tag-0'}}}, 'mediaTypes': {'banner': {'sizes': [[320, 480], [320, 50]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '71c0d86b-4b47-4aff-a6da-1af0b1712439', 'sizes': [[320, 480], [320, 50]], 'bidId': '264d7969b125a5', 'bidderRequestId': '1c674c14a3889c', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}];
const c_VALIDBIDAPPREQUESTS = [{'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com\/rtb\/v2\/', 'tappxkey': 'pub-1234-android-1234', 'endpoint': 'ZZ1234PBJS', 'bidfloor': 0.005, 'test': 1, 'app': {'name': 'Tappx Test', 'bundle': 'com.test.tappx', 'domain': 'tappx.com', 'publisher': { 'name': 'Tappx', 'domain': 'tappx.com' }}}, 'userId': {'haloId': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'id5id': {'uid': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'ext': {'linkType': 0}}, 'intentIqId': 'GIF89a\u0001\u0000\u0001\u0000�\u0000\u0000���\u0000\u0000\u0000!�\u0004\u0001\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;', 'lotamePanoramaId': '8003916b61a95b185690ec103bdf4945a70213e01818a5e5d8690b542730755a', 'parrableId': {'eid': '01.1617088921.7faa68d9570a50ea8e4f359e9b99ca4b7509e948a6175b3e5b0b8cbaf5b62424104ccfb0191ca79366de8368ed267b89a68e236df5f41f96f238e4301659e9023fec05e46399fb1ad0a0'}, 'pubcid': 'b7143795-852f-42f0-8864-5ecbea1ade4e', 'pubProvidedId': [{'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}]}, 'userIdAsEids': [{'source': 'audigent.com', 'uids': [{'id': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'atype': 1}]}, {'source': 'id5-sync.com', 'uids': [{'id': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'atype': 1, 'ext': {'linkType': 0}}]}, {'source': 'intentiq.com', 'uids': [{'id': 'GIF89a\u0001\u0000\u0001\u0000�\u0000\u0000���\u0000\u0000\u0000!�\u0004\u0001\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;', 'atype': 1}]}, {'source': 'crwdcntrl.net', 'uids': [{'id': '8003916b61a95b185690ec103bdf4945a70213e01818a5e5d8690b542730755a', 'atype': 1}]}, {'source': 'parrable.com', 'uids': [{'id': '01.1617088921.7faa68d9570a50ea8e4f359e9b99ca4b7509e948a6175b3e5b0b8cbaf5b62424104ccfb0191ca79366de8368ed267b89a68e236df5f41f96f238e4301659e9023fec05e46399fb1ad0a0', 'atype': 1}]}, {'source': 'pubcid.org', 'uids': [{'id': 'b7143795-852f-42f0-8864-5ecbea1ade4e', 'atype': 1}]}, {'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}], 'ortb2Imp': {'ext': {'data': {'adserver': {'name': 'gam', 'adslot': '/19968336/header-bid-tag-0'}, 'pbadslot': '/19968336/header-bid-tag-0'}}}, 'mediaTypes': {'banner': {'sizes': [[320, 480], [320, 50]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '71c0d86b-4b47-4aff-a6da-1af0b1712439', 'sizes': [[320, 480], [320, 50]], 'bidId': '264d7969b125a5', 'bidderRequestId': '1c674c14a3889c', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}];
-const c_BIDDERREQUEST_B = {'bidderCode': 'tappx', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'bidderRequestId': '1c674c14a3889c', 'bids': [{'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com\/rtb\/v2\/', 'tappxkey': 'pub-1234-android-1234', 'endpoint': 'ZZ1234PBJS', 'bidfloor': 0.005, 'test': 1}, 'userId': {'haloId': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'id5id': {'uid': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'ext': {'linkType': 0}}, 'intentIqId': 'GIF89a\u0000\u0000\u0000\u0000�\u0000\u0000���\u0000\u0000\u0000?�\u0000\u0000\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000A\u0000\u0000;', 'lotamePanoramaId': '8003916b61a95b185690ec103bdf4945a70213e01818a5e5d8690b542730755a', 'parrableId': {'eid': '01.1617088921.7faa68d9570a50ea8e4f359e9b99ca4b7509e948a6175b3e5b0b8cbaf5b62424104ccfb0191ca79366de8368ed267b89a68e236df5f41f96f238e4301659e9023fec05e46399fb1ad0a0'}, 'pubcid': 'b7143795-852f-42f0-8864-5ecbea1ade4e', 'pubProvidedId': [{'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}]}, 'userIdAsEids': [{'source': 'audigent.com', 'uids': [{'id': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'atype': 1}]}, {'source': 'id5-sync.com', 'uids': [{'id': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'atype': 1, 'ext': {'linkType': 0}}]}], 'ortb2Imp': {'ext': {'data': {'adserver': {'name': 'gam', 'adslot': '/19968336/header-bid-tag-0'}, 'pbadslot': '/19968336/header-bid-tag-0'}}}, 'mediaTypes': {'banner': {'sizes': [[320, 480], [320, 50]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '71c0d86b-4b47-4aff-a6da-1af0b1712439', 'sizes': [[320, 480], [320, 50]], 'bidId': '264d7969b125a5', 'bidderRequestId': '1c674c14a3889c', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}], 'auctionStart': 1617088922120, 'timeout': 700, 'refererInfo': {'referer': 'http://localhost:9999/integrationExamples/gpt/gdpr_hello_world.html?pbjs_debug=true', 'reachedTop': true, 'isAmp': false, 'numIframes': 0, 'stack': ['http://localhost:9999/integrationExamples/gpt/gdpr_hello_world.html?pbjs_debug=true'], 'canonicalUrl': null}, 'gdprConsent': {'consentString': c_CONSENTSTRING, 'vendorData': {'metadata': 'BO-JeiTPABAOkAAABAENABA', 'gdprApplies': true, 'hasGlobalScope': false, 'cookieVersion': 1, 'created': '2020-12-09T09:22:09.900Z', 'lastUpdated': '2021-01-14T15:44:03.600Z', 'cmpId': 0, 'cmpVersion': 1, 'consentScreen': 0, 'consentLanguage': 'EN', 'vendorListVersion': 1, 'maxVendorId': 0, 'purposeConsents': {}, 'vendorConsents': {}}, 'gdprApplies': true, 'apiVersion': 1}, 'uspConsent': '1YCC', 'start': 1611308859099};
+const c_BIDDERREQUEST_B = {'bidderCode': 'tappx', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'bidderRequestId': '1c674c14a3889c', 'bids': [{'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com\/rtb\/v2\/', 'tappxkey': 'pub-1234-android-1234', 'endpoint': 'ZZ1234PBJS', 'bidfloor': 0.005, 'test': 1}, 'userId': {'haloId': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'id5id': {'uid': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'ext': {'linkType': 0}}, 'intentIqId': 'GIF89a\u0000\u0000\u0000\u0000�\u0000\u0000���\u0000\u0000\u0000?�\u0000\u0000\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000A\u0000\u0000;', 'lotamePanoramaId': '8003916b61a95b185690ec103bdf4945a70213e01818a5e5d8690b542730755a', 'parrableId': {'eid': '01.1617088921.7faa68d9570a50ea8e4f359e9b99ca4b7509e948a6175b3e5b0b8cbaf5b62424104ccfb0191ca79366de8368ed267b89a68e236df5f41f96f238e4301659e9023fec05e46399fb1ad0a0'}, 'pubcid': 'b7143795-852f-42f0-8864-5ecbea1ade4e', 'pubProvidedId': [{'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}]}, 'userIdAsEids': [{'source': 'audigent.com', 'uids': [{'id': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'atype': 1}]}, {'source': 'id5-sync.com', 'uids': [{'id': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'atype': 1, 'ext': {'linkType': 0}}]}], 'ortb2Imp': {'ext': {'data': {'adserver': {'name': 'gam', 'adslot': '/19968336/header-bid-tag-0'}, 'pbadslot': '/19968336/header-bid-tag-0'}}}, 'mediaTypes': {'banner': {'sizes': [[320, 480], [320, 50]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '71c0d86b-4b47-4aff-a6da-1af0b1712439', 'sizes': [[320, 480], [320, 50]], 'bidId': '264d7969b125a5', 'bidderRequestId': '1c674c14a3889c', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}], 'auctionStart': 1617088922120, 'timeout': 700, 'refererInfo': {'page': 'http://localhost:9999/integrationExamples/gpt/gdpr_hello_world.html?pbjs_debug=true', 'reachedTop': true, 'isAmp': false, 'numIframes': 0, 'stack': ['http://localhost:9999/integrationExamples/gpt/gdpr_hello_world.html?pbjs_debug=true'], 'canonicalUrl': null}, 'gdprConsent': {'consentString': c_CONSENTSTRING, 'vendorData': {'metadata': 'BO-JeiTPABAOkAAABAENABA', 'gdprApplies': true, 'hasGlobalScope': false, 'cookieVersion': 1, 'created': '2020-12-09T09:22:09.900Z', 'lastUpdated': '2021-01-14T15:44:03.600Z', 'cmpId': 0, 'cmpVersion': 1, 'consentScreen': 0, 'consentLanguage': 'EN', 'vendorListVersion': 1, 'maxVendorId': 0, 'purposeConsents': {}, 'vendorConsents': {}}, 'gdprApplies': true, 'apiVersion': 1}, 'uspConsent': '1YCC', 'start': 1611308859099};
const c_BIDDERREQUEST_V = {'method': 'POST', 'url': 'https://testing.ssp.tappx.com/rtb/v2//VZ12TESTCTV?type_cnn=prebidjs&v=0.1.10329', 'data': '{"site":{"name":"localhost","bundle":"localhost","domain":"localhost"},"user":{"ext":{}},"id":"0fecfa84-c541-49f8-8c45-76b90fddc30e","test":1,"at":1,"tmax":1000,"bidder":"tappx","imp":[{"video":{"mimes":["video/mp4","application/javascript"],"minduration":3,"maxduration":30,"startdelay":5,"playbackmethod":[1,3],"api":[1,2],"protocols":[2,3],"battr":[13,14],"linearity":1,"placement":2,"minbitrate":10,"maxbitrate":10,"w":320,"h":250},"id":"2398241a5a860b","tagid":"localhost_typeAdBanVid_windows","secure":1,"bidfloor":0.005,"ext":{"bidder":{"tappxkey":"pub-1234-desktop-1234","endpoint":"vz34906po","host":"https://vz34906po.pub.tappx.com/rtb/","bidfloor":0.005}}}],"device":{"os":"windows","ip":"peer","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36","h":864,"w":1536,"dnt":0,"language":"en","make":"Google Inc."},"params":{"host":"tappx.com","bidfloor":0.005},"regs":{"gdpr":0,"ext":{}}}', 'bids': {'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com/rtb/v2/', 'tappxkey': 'pub-1234-desktop-1234', 'endpoint': 'VZ12TESTCTV', 'bidfloor': 0.005, 'test': true}, 'crumbs': {'pubcid': 'dccfe922-3823-4676-b7b2-e5ed8743154e'}, 'ortb2Imp': {'ext': {'data': {'pbadslot': 'video-ad-div'}}}, 'renderer': {'options': {'text': 'Tappx Outstream Video'}}, 'mediaTypes': {'video': {'mimes': ['video/mp4', 'application/javascript'], 'minduration': 3, 'maxduration': 30, 'startdelay': 5, 'playbackmethod': [1, 3], 'api': [1, 2], 'protocols': [2, 3], 'battr': [13, 14], 'linearity': 1, 'placement': 2, 'minbitrate': 10, 'maxbitrate': 10, 'w': 320, 'h': 250}}, 'adUnitCode': 'video-ad-div', 'transactionId': 'ed41c805-d14c-49c3-954d-26b98b2aa2c2', 'sizes': [[320, 250]], 'bidId': '28f49c71b13f2f', 'bidderRequestId': '1401710496dc7', 'auctionId': 'e807363f-3095-43a8-a4a6-f44196cb7318', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}}
const c_BIDDERREQUEST_VOutstream = {'method': 'POST', 'url': 'https://testing.ssp.tappx.com/rtb/v2//VZ12TESTCTV?type_cnn=prebidjs&v=0.1.10329', 'data': '{"site":{"name":"localhost","bundle":"localhost","domain":"localhost"},"user":{"ext":{}},"id":"0fecfa84-c541-49f8-8c45-76b90fddc30e","test":1,"at":1,"tmax":1000,"bidder":"tappx","imp":[{"video":{"context": "outstream","playerSize":[640, 480],"mimes":["video/mp4","application/javascript"],"minduration":3,"maxduration":30,"startdelay":5,"playbackmethod":[1,3],"api":[1,2],"protocols":[2,3],"battr":[13,14],"linearity":1,"placement":2,"minbitrate":10,"maxbitrate":10,"w":320,"h":250},"id":"2398241a5a860b","tagid":"localhost_typeAdBanVid_windows","secure":1,"bidfloor":0.005,"ext":{"bidder":{"tappxkey":"pub-1234-desktop-1234","endpoint":"vz34906po","host":"https://vz34906po.pub.tappx.com/rtb/","bidfloor":0.005}}}],"device":{"os":"windows","ip":"peer","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36","h":864,"w":1536,"dnt":0,"language":"en","make":"Google Inc."},"params":{"host":"tappx.com","bidfloor":0.005},"regs":{"gdpr":0,"ext":{}}}', 'bids': {'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com/rtb/v2/', 'tappxkey': 'pub-1234-desktop-1234', 'endpoint': 'VZ12TESTCTV', 'bidfloor': 0.005, 'test': true}, 'crumbs': {'pubcid': 'dccfe922-3823-4676-b7b2-e5ed8743154e'}, 'ortb2Imp': {'ext': {'data': {'pbadslot': 'video-ad-div'}}}, 'renderer': {'options': {'text': 'Tappx Outstream Video'}}, 'mediaTypes': {'video': {'mimes': ['video/mp4', 'application/javascript'], 'minduration': 3, 'maxduration': 30, 'startdelay': 5, 'playbackmethod': [1, 3], 'api': [1, 2], 'protocols': [2, 3], 'battr': [13, 14], 'linearity': 1, 'placement': 2, 'minbitrate': 10, 'maxbitrate': 10, 'w': 320, 'h': 250}}, 'adUnitCode': 'video-ad-div', 'transactionId': 'ed41c805-d14c-49c3-954d-26b98b2aa2c2', 'sizes': [[320, 250]], 'bidId': '28f49c71b13f2f', 'bidderRequestId': '1401710496dc7', 'auctionId': 'e807363f-3095-43a8-a4a6-f44196cb7318', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}}
diff --git a/test/spec/modules/targetVideoBidAdapter_spec.js b/test/spec/modules/targetVideoBidAdapter_spec.js
index 0ce6f0fb70d..adbc982e509 100644
--- a/test/spec/modules/targetVideoBidAdapter_spec.js
+++ b/test/spec/modules/targetVideoBidAdapter_spec.js
@@ -93,4 +93,47 @@ describe('TargetVideo Bid Adapter', function() {
expect(bid.ad).to.include('')
expect(bid.ad).to.include('initPlayer')
});
+
+ it('Test GDPR consent information is present in the request', function () {
+ let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
+ let bidderRequest = {
+ 'bidderCode': 'targetVideo',
+ 'auctionId': '1d1a030790a475',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'timeout': 3000,
+ 'gdprConsent': {
+ consentString: consentString,
+ gdprApplies: true,
+ addtlConsent: '1~7.12.35.62.66.70.89.93.108'
+ }
+ };
+ bidderRequest.bids = bannerRequest;
+
+ const request = spec.buildRequests(bannerRequest, bidderRequest);
+ expect(request.options).to.deep.equal({withCredentials: true});
+ const payload = JSON.parse(request.data);
+
+ expect(payload.gdpr_consent).to.exist;
+ expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString);
+ expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true;
+ expect(payload.gdpr_consent.addtl_consent).to.exist.and.to.deep.equal([7, 12, 35, 62, 66, 70, 89, 93, 108]);
+ });
+
+ it('Test US Privacy string is present in the request', function() {
+ let consentString = '1YA-';
+ let bidderRequest = {
+ 'bidderCode': 'targetVideo',
+ 'auctionId': '1d1a030790a475',
+ 'bidderRequestId': '22edbae2733bf6',
+ 'timeout': 3000,
+ 'uspConsent': consentString
+ };
+ bidderRequest.bids = bannerRequest;
+
+ const request = spec.buildRequests(bannerRequest, bidderRequest);
+ const payload = JSON.parse(request.data);
+
+ expect(payload.us_privacy).to.exist;
+ expect(payload.us_privacy).to.exist.and.to.equal(consentString);
+ });
});
diff --git a/test/spec/modules/teadsBidAdapter_spec.js b/test/spec/modules/teadsBidAdapter_spec.js
index 75ed7452b57..254f23d011e 100644
--- a/test/spec/modules/teadsBidAdapter_spec.js
+++ b/test/spec/modules/teadsBidAdapter_spec.js
@@ -147,9 +147,9 @@ describe('teadsBidAdapter', () => {
'consentString': consentString,
'gdprApplies': true,
'vendorData': {
- 'hasGlobalConsent': false
+ 'isServiceSpecific': true
},
- 'apiVersion': 1
+ 'apiVersion': 2
}
};
@@ -159,14 +159,14 @@ describe('teadsBidAdapter', () => {
expect(payload.gdpr_iab).to.exist;
expect(payload.gdpr_iab.consent).to.equal(consentString);
expect(payload.gdpr_iab.status).to.equal(12);
- expect(payload.gdpr_iab.apiVersion).to.equal(1);
+ expect(payload.gdpr_iab.apiVersion).to.equal(2);
});
it('should add referer info to payload', function () {
const bidRequest = Object.assign({}, bidRequests[0])
const bidderRequest = {
refererInfo: {
- referer: 'https://example.com/page.html',
+ page: 'https://example.com/page.html',
reachedTop: true,
numIframes: 2
}
@@ -245,9 +245,9 @@ describe('teadsBidAdapter', () => {
'consentString': consentString,
'gdprApplies': true,
'vendorData': {
- 'hasGlobalScope': true
+ 'isServiceSpecific': false,
},
- 'apiVersion': 1
+ 'apiVersion': 2
}
};
@@ -257,7 +257,7 @@ describe('teadsBidAdapter', () => {
expect(payload.gdpr_iab).to.exist;
expect(payload.gdpr_iab.consent).to.equal(consentString);
expect(payload.gdpr_iab.status).to.equal(11);
- expect(payload.gdpr_iab.apiVersion).to.equal(1);
+ expect(payload.gdpr_iab.apiVersion).to.equal(2);
});
it('should send GDPR TCF2 to endpoint with 12 status', function() {
@@ -294,7 +294,7 @@ describe('teadsBidAdapter', () => {
'consentString': undefined,
'gdprApplies': undefined,
'vendorData': undefined,
- 'apiVersion': 1
+ 'apiVersion': 2
}
};
@@ -304,7 +304,7 @@ describe('teadsBidAdapter', () => {
expect(payload.gdpr_iab).to.exist;
expect(payload.gdpr_iab.consent).to.equal('');
expect(payload.gdpr_iab.status).to.equal(22);
- expect(payload.gdpr_iab.apiVersion).to.equal(1);
+ expect(payload.gdpr_iab.apiVersion).to.equal(2);
});
it('should send GDPR to endpoint with 0 status', function() {
@@ -319,7 +319,7 @@ describe('teadsBidAdapter', () => {
'vendorData': {
'hasGlobalScope': false
},
- 'apiVersion': 1
+ 'apiVersion': 2
}
};
@@ -329,7 +329,7 @@ describe('teadsBidAdapter', () => {
expect(payload.gdpr_iab).to.exist;
expect(payload.gdpr_iab.consent).to.equal(consentString);
expect(payload.gdpr_iab.status).to.equal(0);
- expect(payload.gdpr_iab.apiVersion).to.equal(1);
+ expect(payload.gdpr_iab.apiVersion).to.equal(2);
});
it('should send GDPR to endpoint with 0 status when gdprApplies = false (vendorData = undefined)', function() {
@@ -341,7 +341,7 @@ describe('teadsBidAdapter', () => {
'consentString': undefined,
'gdprApplies': false,
'vendorData': undefined,
- 'apiVersion': 1
+ 'apiVersion': 2
}
};
@@ -351,7 +351,7 @@ describe('teadsBidAdapter', () => {
expect(payload.gdpr_iab).to.exist;
expect(payload.gdpr_iab.consent).to.equal('');
expect(payload.gdpr_iab.status).to.equal(0);
- expect(payload.gdpr_iab.apiVersion).to.equal(1);
+ expect(payload.gdpr_iab.apiVersion).to.equal(2);
});
it('should send GDPR to endpoint with 12 status when apiVersion = 0', function() {
@@ -364,7 +364,7 @@ describe('teadsBidAdapter', () => {
'consentString': consentString,
'gdprApplies': true,
'vendorData': {
- 'hasGlobalScope': false
+ 'isServiceSpecific': true
},
'apiVersion': 0
}
@@ -470,85 +470,89 @@ describe('teadsBidAdapter', () => {
'deviceWidth': 1680
};
- describe('FLoC ID', function () {
- it('should not add cohortId and cohortVersion params to payload if FLoC ID system is not enabled', function () {
+ const userIdModules = {
+ unifiedId2: {uid2: {id: 'unifiedId2-id'}},
+ liveRampId: {idl_env: 'liveRampId-id'},
+ lotamePanoramaId: {lotamePanoramaId: 'lotamePanoramaId-id'},
+ id5Id: {id5id: {uid: 'id5Id-id'}},
+ criteoId: {criteoId: 'criteoId-id'},
+ yahooConnectId: {connectId: 'yahooConnectId-id'},
+ quantcastId: {quantcastId: 'quantcastId-id'},
+ epsilonPublisherLinkId: {publinkId: 'epsilonPublisherLinkId-id'},
+ publisherFirstPartyViewerId: {pubcid: 'publisherFirstPartyViewerId-id'},
+ merkleId: {merkleId: {id: 'merkleId-id'}},
+ kinessoId: {kpuid: 'kinessoId-id'}
+ };
+
+ describe('User Id Modules', function () {
+ it(`should not add param to payload if user id system is not enabled`, function () {
const bidRequest = {
...baseBidRequest,
- userId: {} // no "flocId" property -> assumption that the FLoC ID system is disabled
+ userId: {} // no property -> assumption that the system is disabled
};
const request = spec.buildRequests([bidRequest], bidderResquestDefault);
const payload = JSON.parse(request.data);
- expect(payload).not.to.have.property('cohortId');
- expect(payload).not.to.have.property('cohortVersion');
+ for (const userId in userIdModules) {
+ expect(payload, userId).not.to.have.property(userId);
+ }
});
- it('should add cohortId param to payload if FLoC ID system is enabled and ID available, but not version', function () {
- const bidRequest = {
- ...baseBidRequest,
- userId: {
- flocId: {
- id: 'my-floc-id'
- }
- }
- };
-
- const request = spec.buildRequests([bidRequest], bidderResquestDefault);
+ it(`should not add param to payload if user id field is absent`, function () {
+ const request = spec.buildRequests([baseBidRequest], bidderResquestDefault);
const payload = JSON.parse(request.data);
- expect(payload.cohortId).to.equal('my-floc-id');
- expect(payload).not.to.have.property('cohortVersion');
+ for (const userId in userIdModules) {
+ expect(payload, userId).not.to.have.property(userId);
+ }
});
- it('should add cohortId and cohortVersion params to payload if FLoC ID system is enabled', function () {
+ it(`should not add param to payload if user id is enabled but there is no value`, function () {
const bidRequest = {
...baseBidRequest,
userId: {
- flocId: {
- id: 'my-floc-id',
- version: 'chrome.1.1'
- }
+ idl_env: '',
+ pubcid: 'publisherFirstPartyViewerId-id'
}
};
const request = spec.buildRequests([bidRequest], bidderResquestDefault);
const payload = JSON.parse(request.data);
- expect(payload.cohortId).to.equal('my-floc-id');
- expect(payload.cohortVersion).to.equal('chrome.1.1');
+ expect(payload).not.to.have.property('liveRampId');
+ expect(payload['publisherFirstPartyViewerId']).to.equal('publisherFirstPartyViewerId-id');
});
- });
- describe('Unified ID v2', function () {
- it('should not add unifiedId2 param to payload if uid2 system is not enabled', function () {
+ it(`should add userId param to payload for each enabled user id system`, function () {
+ let userIdObject = {};
+ for (const userId in userIdModules) {
+ userIdObject = {
+ ...userIdObject,
+ ...userIdModules[userId]
+ }
+ }
const bidRequest = {
...baseBidRequest,
- userId: {} // no "uid2" property -> assumption that the Unified ID v2 system is disabled
+ userId: userIdObject
};
const request = spec.buildRequests([bidRequest], bidderResquestDefault);
const payload = JSON.parse(request.data);
- expect(payload).not.to.have.property('unifiedId2');
+ expect(payload['unifiedId2']).to.equal('unifiedId2-id');
+ expect(payload['liveRampId']).to.equal('liveRampId-id');
+ expect(payload['lotamePanoramaId']).to.equal('lotamePanoramaId-id');
+ expect(payload['id5Id']).to.equal('id5Id-id');
+ expect(payload['criteoId']).to.equal('criteoId-id');
+ expect(payload['yahooConnectId']).to.equal('yahooConnectId-id');
+ expect(payload['quantcastId']).to.equal('quantcastId-id');
+ expect(payload['epsilonPublisherLinkId']).to.equal('epsilonPublisherLinkId-id');
+ expect(payload['publisherFirstPartyViewerId']).to.equal('publisherFirstPartyViewerId-id');
+ expect(payload['merkleId']).to.equal('merkleId-id');
+ expect(payload['kinessoId']).to.equal('kinessoId-id');
});
-
- it('should add unifiedId2 param to payload if uid2 system is enabled', function () {
- const bidRequest = {
- ...baseBidRequest,
- userId: {
- uid2: {
- id: 'my-unified-id-2'
- }
- }
- };
-
- const request = spec.buildRequests([bidRequest], bidderResquestDefault);
- const payload = JSON.parse(request.data);
-
- expect(payload.unifiedId2).to.equal('my-unified-id-2');
- })
- });
+ })
describe('First-party cookie Teads ID', function () {
it('should not add firstPartyCookieTeadsId param to payload if cookies are not enabled', function () {
diff --git a/test/spec/modules/tncIdSystem_spec.js b/test/spec/modules/tncIdSystem_spec.js
new file mode 100644
index 00000000000..57c5fa63645
--- /dev/null
+++ b/test/spec/modules/tncIdSystem_spec.js
@@ -0,0 +1,109 @@
+import { tncidSubModule } from 'modules/tncIdSystem';
+
+const consentData = {
+ gdprApplies: true,
+ consentString: 'GDPR_CONSENT_STRING'
+};
+
+describe('TNCID tests', function () {
+ describe('name', () => {
+ it('should expose the name of the submodule', () => {
+ expect(tncidSubModule.name).to.equal('tncId');
+ });
+ });
+
+ describe('gvlid', () => {
+ it('should expose the vendor id', () => {
+ expect(tncidSubModule.gvlid).to.equal(750);
+ });
+ });
+
+ describe('decode', () => {
+ it('should wrap the given value inside an object literal', () => {
+ expect(tncidSubModule.decode('TNCID_TEST_ID')).to.deep.equal({
+ tncid: 'TNCID_TEST_ID'
+ });
+ });
+ });
+
+ describe('getId', () => {
+ afterEach(function () {
+ Object.defineProperty(window, '__tnc', {value: undefined, configurable: true});
+ Object.defineProperty(window, '__tncPbjs', {value: undefined, configurable: true});
+ });
+
+ it('Should NOT give TNCID if GDPR applies but consent string is missing', function () {
+ const res = tncidSubModule.getId({}, { gdprApplies: true });
+ expect(res).to.be.undefined;
+ });
+
+ it('GDPR is OK and page has no TNC script on page, script goes in error, no TNCID is returned', function () {
+ const completeCallback = sinon.spy();
+ const {callback} = tncidSubModule.getId({}, consentData);
+
+ return callback(completeCallback).then(() => {
+ expect(completeCallback.calledOnce).to.be.true;
+ })
+ });
+
+ it('GDPR is OK and page has TNC script with ns: __tnc, present TNCID is returned', function () {
+ Object.defineProperty(window, '__tnc', {
+ value: {
+ ready: (readyFunc) => { readyFunc() },
+ on: (name, cb) => { cb() },
+ tncid: 'TNCID_TEST_ID_1',
+ providerId: 'TEST_PROVIDER_ID_1',
+ },
+ configurable: true
+ });
+
+ const completeCallback = sinon.spy();
+ const {callback} = tncidSubModule.getId({}, { gdprApplies: false });
+
+ return callback(completeCallback).then(() => {
+ expect(completeCallback.calledOnceWithExactly('TNCID_TEST_ID_1')).to.be.true;
+ })
+ });
+
+ it('GDPR is OK and page has TNC script with ns: __tnc but not loaded, TNCID is assigned and returned', function () {
+ Object.defineProperty(window, '__tnc', {
+ value: {
+ ready: (readyFunc) => { readyFunc() },
+ on: (name, cb) => { cb() },
+ providerId: 'TEST_PROVIDER_ID_1',
+ },
+ configurable: true
+ });
+
+ const completeCallback = sinon.spy();
+ const {callback} = tncidSubModule.getId({}, { gdprApplies: false });
+
+ return callback(completeCallback).then(() => {
+ expect(completeCallback.calledOnceWithExactly(undefined)).to.be.true;
+ })
+ });
+
+ it('GDPR is OK and page has TNC script with ns: __tncPbjs, TNCID is returned', function () {
+ Object.defineProperty(window, '__tncPbjs', {
+ value: {
+ ready: (readyFunc) => { readyFunc() },
+ on: (name, cb) => {
+ window.__tncPbjs.tncid = 'TNCID_TEST_ID_2';
+ cb();
+ },
+ providerId: 'TEST_PROVIDER_ID_1',
+ options: {},
+ },
+ configurable: true,
+ writable: true
+ });
+
+ const completeCallback = sinon.spy();
+ const {callback} = tncidSubModule.getId({params: {url: 'TEST_URL'}}, consentData);
+
+ return callback(completeCallback).then(() => {
+ expect(completeCallback.calledOnceWithExactly('TNCID_TEST_ID_2')).to.be.true;
+ })
+ });
+ });
+});
diff --git a/test/spec/modules/topicsFpdModule_spec.js b/test/spec/modules/topicsFpdModule_spec.js
new file mode 100644
index 00000000000..3781768497b
--- /dev/null
+++ b/test/spec/modules/topicsFpdModule_spec.js
@@ -0,0 +1,239 @@
+import {getTopics, getTopicsData, processFpd} from '../../../modules/topicsFpdModule.js';
+import {deepClone} from '../../../src/utils.js';
+
+describe('getTopicsData', () => {
+ function makeTopic(topic, modelv, taxv = '1') {
+ return {
+ topic,
+ taxonomyVersion: taxv,
+ modelVersion: modelv
+ }
+ }
+
+ function byTaxClass(segments) {
+ return segments.reduce((memo, segment) => {
+ memo[`${segment.ext.segtax}:${segment.ext.segclass}`] = segment;
+ return memo;
+ }, {})
+ }
+
+ [
+ {
+ t: 'no topics',
+ topics: [],
+ expected: []
+ },
+ {
+ t: 'single topic',
+ topics: [makeTopic(123, 'm1')],
+ expected: [
+ {
+ ext: {
+ segtax: 600,
+ segclass: 'm1'
+ },
+ segment: [
+ {id: '123'}
+ ]
+ }
+ ]
+ },
+ {
+ t: 'multiple topics with the same model version',
+ topics: [makeTopic(123, 'm1'), makeTopic(321, 'm1')],
+ expected: [
+ {
+ ext: {
+ segtax: 600,
+ segclass: 'm1'
+ },
+ segment: [
+ {id: '123'},
+ {id: '321'}
+ ]
+ }
+ ]
+ },
+ {
+ t: 'multiple topics with different model versions',
+ topics: [makeTopic(1, 'm1'), makeTopic(2, 'm1'), makeTopic(3, 'm2')],
+ expected: [
+ {
+ ext: {
+ segtax: 600,
+ segclass: 'm1'
+ },
+ segment: [
+ {id: '1'},
+ {id: '2'}
+ ]
+ },
+ {
+ ext: {
+ segtax: 600,
+ segclass: 'm2'
+ },
+ segment: [
+ {id: '3'}
+ ]
+ }
+ ]
+ },
+ {
+ t: 'multiple topics, some with a taxonomy version other than "1"',
+ topics: [makeTopic(123, 'm1'), makeTopic(321, 'm1', 'other')],
+ expected: [
+ {
+ ext: {
+ segtax: 600,
+ segclass: 'm1'
+ },
+ segment: [
+ {id: '123'}
+ ]
+ }
+ ]
+ },
+ {
+ t: 'multiple topics in multiple taxonomies',
+ taxonomies: {
+ '1': 600,
+ '2': 601
+ },
+ topics: [
+ makeTopic(123, 'm1', '1'),
+ makeTopic(321, 'm1', '2'),
+ makeTopic(213, 'm2', '1'),
+ ],
+ expected: [
+ {
+ ext: {
+ segtax: 600,
+ segclass: 'm1'
+ },
+ segment: [
+ {id: '123'}
+ ]
+ },
+ {
+ ext: {
+ segtax: 601,
+ segclass: 'm1',
+ },
+ segment: [
+ {id: '321'}
+ ]
+ },
+ {
+ ext: {
+ segtax: 600,
+ segclass: 'm2'
+ },
+ segment: [
+ {id: '213'}
+ ]
+ }
+ ]
+ }
+ ].forEach(({t, topics, expected, taxonomies}) => {
+ describe(`on ${t}`, () => {
+ it('should convert topics to user.data segments correctly', () => {
+ const actual = getTopicsData('mockName', topics, taxonomies);
+ expect(actual.length).to.eql(expected.length);
+ expected = byTaxClass(expected);
+ Object.entries(byTaxClass(actual)).forEach(([key, datum]) => {
+ sinon.assert.match(datum, expected[key]);
+ expect(datum.name).to.equal('mockName');
+ })
+ });
+
+ it('should not set name if null', () => {
+ getTopicsData(null, topics).forEach((data) => {
+ expect(data.hasOwnProperty('name')).to.be.false;
+ })
+ })
+ })
+ })
+});
+
+describe('getTopics', () => {
+ Object.entries({
+ 'document with no browsingTopics': {},
+ 'document that disallows topics': {
+ featurePolicy: {
+ allowsFeature: sinon.stub().returns(false)
+ }
+ },
+ 'document that throws on featurePolicy': {
+ browsingTopics: sinon.stub(),
+ get featurePolicy() {
+ throw new Error()
+ }
+ },
+ 'document that throws on browsingTopics': {
+ browsingTopics: sinon.stub().callsFake(() => { throw new Error(); }),
+ featurePolicy: {
+ allowsFeature: sinon.stub().returns(true)
+ }
+ },
+ }).forEach(([t, doc]) => {
+ it(`should resolve to an empty list on ${t}`, () => {
+ return getTopics(doc).then((topics) => {
+ expect(topics).to.eql([]);
+ });
+ })
+ });
+
+ it('should call `document.browsingTopics` when allowed', () => {
+ const topics = ['t1', 't2']
+ return getTopics({
+ browsingTopics: sinon.stub().returns(Promise.resolve(topics)),
+ featurePolicy: {
+ allowsFeature: sinon.stub().returns(true)
+ }
+ }).then((actual) => {
+ expect(actual).to.eql(topics);
+ })
+ })
+})
+
+describe('processFpd', () => {
+ const mockData = [
+ {
+ name: 'domain',
+ segment: [{id: 123}]
+ },
+ {
+ name: 'domain',
+ segment: [{id: 321}]
+ }
+ ];
+
+ it('should add topics data', () => {
+ return processFpd({}, {global: {}}, {data: Promise.resolve(mockData)})
+ .then(({global}) => {
+ expect(global.user.data).to.eql(mockData);
+ });
+ });
+
+ it('should apppend to existing user.data', () => {
+ const global = {
+ user: {
+ data: [
+ {name: 'preexisting'},
+ ]
+ }
+ };
+ return processFpd({}, {global: deepClone(global)}, {data: Promise.resolve(mockData)})
+ .then((data) => {
+ expect(data.global.user.data).to.eql(global.user.data.concat(mockData));
+ });
+ });
+
+ it('should not modify fpd when there is no data', () => {
+ return processFpd({}, {global: {}}, {data: Promise.resolve([])})
+ .then((data) => {
+ expect(data.global).to.eql({});
+ });
+ });
+});
diff --git a/test/spec/modules/tpmnBidAdapter_spec.js b/test/spec/modules/tpmnBidAdapter_spec.js
index 468769c2573..e2b14b18f61 100644
--- a/test/spec/modules/tpmnBidAdapter_spec.js
+++ b/test/spec/modules/tpmnBidAdapter_spec.js
@@ -98,7 +98,7 @@ describe('tpmnAdapterTests', function () {
const tempBidRequests = [bid];
const tempBidderRequest = {
refererInfo: {
- referer: 'http://localhost/test',
+ page: 'http://localhost/test',
site: {
domain: 'localhost',
page: 'http://localhost/test'
diff --git a/test/spec/modules/trafficgateBidAdapter_spec.js b/test/spec/modules/trafficgateBidAdapter_spec.js
new file mode 100644
index 00000000000..ecea0e69ca1
--- /dev/null
+++ b/test/spec/modules/trafficgateBidAdapter_spec.js
@@ -0,0 +1,223 @@
+import { expect } from 'chai'
+import { spec } from '../../../modules/trafficgateBidAdapter'
+import { deepStrictEqual, notStrictEqual, ok, strictEqual } from 'assert'
+
+describe('TrafficGateAdapter', () => {
+ const bid = {
+ bidId: '9ec5b177515ee2e5',
+ bidder: 'trafficgate',
+ params: {
+ placementId: 1,
+ host: 'example'
+ },
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250]]
+ }
+ }
+ }
+
+ describe('isBidRequestValid', () => {
+ it('Should return true if there are bidId, params and placementId parameters present', () => {
+ strictEqual(true, spec.isBidRequestValid(bid))
+ })
+
+ it('Should return false if at least one of parameters is not present', () => {
+ const b = { ...bid }
+ delete b.params.placementId
+ strictEqual(false, spec.isBidRequestValid(b))
+ })
+
+ it('Should return false if at least one of parameters is not present', () => {
+ const b = { ...bid }
+ delete b.params.host
+ strictEqual(false, spec.isBidRequestValid(b))
+ })
+ })
+
+ describe('buildRequests', () => {
+ const serverRequest = spec.buildRequests([bid])
+
+ it('Creates a ServerRequest object with method, URL and data', () => {
+ ok(serverRequest)
+ ok(serverRequest.method)
+ ok(serverRequest.url)
+ ok(serverRequest.data)
+ })
+
+ it('Returns POST method', () => {
+ strictEqual('POST', serverRequest.method)
+ })
+
+ it('Returns valid URL', () => {
+ strictEqual('https://example.bc-plugin.com/?c=o&m=multi', serverRequest.url)
+ })
+
+ it('Returns valid data if array of bids is valid', () => {
+ const { data } = serverRequest
+ strictEqual('object', typeof data)
+ deepStrictEqual(['language', 'secure', 'host', 'page', 'placements'], Object.keys(data))
+ strictEqual('string', typeof data.language)
+ strictEqual('string', typeof data.host)
+ strictEqual('string', typeof data.page)
+ notStrictEqual(-1, [0, 1].indexOf(data.secure))
+
+ const placement = data.placements[0]
+ deepStrictEqual(['placementId', 'bidId', 'traffic'], Object.keys(placement))
+ strictEqual(1, placement.placementId)
+ strictEqual('9ec5b177515ee2e5', placement.bidId)
+ strictEqual('banner', placement.traffic)
+ })
+
+ it('Returns empty data if no valid requests are passed', () => {
+ deepStrictEqual([], spec.buildRequests([]))
+ })
+ })
+
+ describe('interpretResponse', () => {
+ const validData = [
+ {
+ body: [{
+ mediaType: 'banner',
+ width: 300,
+ height: 250,
+ cpm: 0.4,
+ ad: 'Test',
+ requestId: '9ec5b177515ee2e5',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1',
+ meta: {
+ advertiserDomains: ['test.com']
+ }
+ }]
+ },
+ {
+ body: [{
+ vastUrl: 'example.com',
+ mediaType: 'video',
+ cpm: 0.5,
+ requestId: '9ec5b177515ee2e5',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1',
+ meta: {
+ advertiserDomains: ['test.com']
+ }
+ }]
+ },
+ {
+ body: [{
+ mediaType: 'native',
+ clickUrl: 'example.com',
+ title: 'Test',
+ image: 'example.com',
+ creativeId: '2',
+ impressionTrackers: ['example.com'],
+ ttl: 120,
+ cpm: 0.4,
+ requestId: '9ec5b177515ee2e5',
+ netRevenue: true,
+ currency: 'USD',
+ meta: {
+ advertiserDomains: ['test.com']
+ }
+ }]
+ }
+ ]
+
+ for (const obj of validData) {
+ const { mediaType } = obj.body[0]
+
+ it(`Should interpret ${mediaType} response`, () => {
+ const response = spec.interpretResponse(obj)
+
+ expect(response).to.be.an('array')
+ strictEqual(1, response.length)
+
+ const copy = { ...obj.body[0] }
+ deepStrictEqual(copy, response[0])
+ })
+ }
+
+ for (const obj of validData) {
+ it(`Should interpret response has meta.advertiserDomains`, () => {
+ const response = spec.interpretResponse(obj)
+
+ expect(response[0]['meta']['advertiserDomains']).to.be.an('array')
+ expect(response[0]['meta']['advertiserDomains'][0]).to.be.an('string')
+ })
+ }
+
+ const invalidData = [
+ {
+ body: [{
+ width: 300,
+ cpm: 0.4,
+ ad: 'Test',
+ requestId: '9ec5b177515ee2e5',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1'
+ }]
+ },
+ {
+ body: [{
+ mediaType: 'video',
+ cpm: 0.5,
+ requestId: '9ec5b177515ee2e5',
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1'
+ }]
+ },
+ {
+ body: [{
+ mediaType: 'native',
+ clickUrl: 'example.com',
+ title: 'Test',
+ impressionTrackers: ['example.com'],
+ ttl: 120,
+ requestId: '9ec5b177515ee2e5',
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ }]
+ }
+ ]
+
+ for (const obj of invalidData) {
+ const { mediaType } = obj.body[0]
+
+ it(`Should return an empty array if invalid ${mediaType} response is passed `, () => {
+ const response = spec.interpretResponse(obj)
+
+ expect(response).to.be.an('array')
+ strictEqual(0, response.length)
+ })
+ }
+
+ it('Should return an empty array if invalid response is passed', () => {
+ const response = spec.interpretResponse({
+ body: [{
+ ttl: 120,
+ creativeId: '2',
+ netRevenue: true,
+ currency: 'USD',
+ dealId: '1'
+ }]
+ })
+
+ expect(response).to.be.an('array')
+ strictEqual(0, response.length)
+ })
+ })
+})
diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js
index 0fc03caa563..d7f09c2a057 100644
--- a/test/spec/modules/trionBidAdapter_spec.js
+++ b/test/spec/modules/trionBidAdapter_spec.js
@@ -71,10 +71,16 @@ describe('Trion adapter tests', function () {
beforeEach(function () {
// adapter = trionAdapter.createNew();
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ trion: {
+ storageAllowed: true
+ }
+ };
sinon.stub(document.body, 'appendChild');
});
afterEach(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
document.body.appendChild.restore();
});
diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js
index fc33a7cd676..e485ae3998f 100644
--- a/test/spec/modules/tripleliftBidAdapter_spec.js
+++ b/test/spec/modules/tripleliftBidAdapter_spec.js
@@ -1,5 +1,5 @@
import { expect } from 'chai';
-import { tripleliftAdapterSpec } from 'modules/tripleliftBidAdapter.js';
+import { tripleliftAdapterSpec, storage } from 'modules/tripleliftBidAdapter.js';
import { newBidder } from 'src/adapters/bidderFactory.js';
import { deepClone } from 'src/utils.js';
import { config } from 'src/config.js';
@@ -345,6 +345,209 @@ describe('triplelift adapter', function () {
auctionId: '1d1a030790a475',
userId: {},
schain,
+ },
+ // outstream video only
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'outstream_test',
+ floor: 1.0,
+ video: {
+ mimes: ['video/mp4'],
+ maxduration: 30,
+ minduration: 6,
+ w: 640,
+ h: 480
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480]
+ }
+ },
+ adUnitCode: 'adunit-code-outstream',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
+ schain,
+ },
+ // banner and incomplete outstream (missing size)
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'outstream_test',
+ floor: 1.0,
+ video: {
+ mimes: ['video/mp4'],
+ maxduration: 30,
+ minduration: 6
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream'
+ },
+ banner: {
+ sizes: [
+ [970, 250],
+ [1, 1]
+ ]
+ }
+ },
+ adUnitCode: 'adunit-code-instream',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
+ schain,
+ },
+ // outstream video; valid placement
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'outstream_test',
+ floor: 1.0,
+ video: {
+ mimes: ['video/mp4'],
+ maxduration: 30,
+ minduration: 6,
+ w: 640,
+ h: 480
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480],
+ placement: 3
+ }
+ },
+ adUnitCode: 'adunit-code-instream',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
+ schain,
+ },
+ // outstream video; valid placement
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'outstream_test',
+ floor: 1.0,
+ video: {
+ mimes: ['video/mp4'],
+ maxduration: 30,
+ minduration: 6,
+ w: 640,
+ h: 480
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480],
+ placement: 4
+ }
+ },
+ adUnitCode: 'adunit-code-instream',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
+ schain,
+ },
+ // outstream video; valid placement
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'outstream_test',
+ floor: 1.0,
+ video: {
+ mimes: ['video/mp4'],
+ maxduration: 30,
+ minduration: 6,
+ w: 640,
+ h: 480
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480],
+ placement: 5
+ }
+ },
+ adUnitCode: 'adunit-code-instream',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
+ schain,
+ },
+ // outstream video; undefined placement
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'outstream_test',
+ floor: 1.0,
+ video: {
+ mimes: ['video/mp4'],
+ maxduration: 30,
+ minduration: 6,
+ w: 640,
+ h: 480
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480]
+ }
+ },
+ adUnitCode: 'adunit-code-instream',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
+ schain,
+ },
+ // outstream video; invalid placement
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'outstream_test',
+ floor: 1.0,
+ video: {
+ mimes: ['video/mp4'],
+ maxduration: 30,
+ minduration: 6,
+ w: 640,
+ h: 480
+ }
+ },
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [640, 480],
+ placement: 6
+ }
+ },
+ adUnitCode: 'adunit-code-instream',
+ sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']],
+ bidId: '30b31c1838de1e',
+ bidderRequestId: '22edbae2733bf6',
+ auctionId: '1d1a030790a475',
+ userId: {},
+ schain,
}
];
@@ -370,7 +573,7 @@ describe('triplelift adapter', function () {
}
],
refererInfo: {
- referer: 'https://examplereferer.com'
+ page: 'https://examplereferer.com'
},
gdprConsent: {
consentString: GDPR_CONSENT_STR,
@@ -379,10 +582,17 @@ describe('triplelift adapter', function () {
};
sandbox = sinon.sandbox.create();
logErrorSpy = sinon.spy(utils, 'logError');
+
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ triplelift: {
+ storageAllowed: true
+ }
+ };
});
afterEach(() => {
sandbox.restore();
utils.logError.restore();
+ $$PREBID_GLOBAL$$.bidderSettings = {};
});
it('exists and is an object', function () {
@@ -408,13 +618,16 @@ describe('triplelift adapter', function () {
expect(payload.imp[0].tagid).to.equal('12345');
expect(payload.imp[0].floor).to.equal(1.0);
expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]);
+ // instream
expect(payload.imp[1].tagid).to.equal('insteam_test');
expect(payload.imp[1].floor).to.equal(1.0);
expect(payload.imp[1].video).to.exist.and.to.be.a('object');
+ expect(payload.imp[1].video.placement).to.equal(1);
// banner and outstream video
- expect(payload.imp[2]).to.not.have.property('video');
+ expect(payload.imp[2]).to.have.property('video');
expect(payload.imp[2]).to.have.property('banner');
expect(payload.imp[2].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]);
+ expect(payload.imp[2].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream', 'placement': 3});
// banner and incomplete video
expect(payload.imp[3]).to.not.have.property('video');
expect(payload.imp[3]).to.have.property('banner');
@@ -427,10 +640,51 @@ describe('triplelift adapter', function () {
expect(payload.imp[5]).to.not.have.property('banner');
expect(payload.imp[5]).to.have.property('video');
expect(payload.imp[5].video).to.exist.and.to.be.a('object');
+ expect(payload.imp[5].video.placement).to.equal(1);
// banner and outream video and native
- expect(payload.imp[6]).to.not.have.property('video');
+ expect(payload.imp[6]).to.have.property('video');
expect(payload.imp[6]).to.have.property('banner');
expect(payload.imp[6].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]);
+ expect(payload.imp[6].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream', 'placement': 3});
+ // outstream video only
+ expect(payload.imp[7]).to.have.property('video');
+ expect(payload.imp[7]).to.not.have.property('banner');
+ expect(payload.imp[7].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream', 'placement': 3});
+ // banner and incomplete outstream (missing size); video request is permitted so banner can still monetize
+ expect(payload.imp[8]).to.have.property('video');
+ expect(payload.imp[8]).to.have.property('banner');
+ expect(payload.imp[8].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]);
+ expect(payload.imp[8].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'context': 'outstream', 'placement': 3});
+ });
+
+ it('should check for valid outstream placement values', function () {
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ const payload = request.data;
+ // outstream video; valid placement
+ expect(payload.imp[9]).to.not.have.property('banner');
+ expect(payload.imp[9]).to.have.property('video');
+ expect(payload.imp[9].video).to.exist.and.to.be.a('object');
+ expect(payload.imp[9].video.placement).to.equal(3);
+ // outstream video; valid placement
+ expect(payload.imp[10]).to.not.have.property('banner');
+ expect(payload.imp[10]).to.have.property('video');
+ expect(payload.imp[10].video).to.exist.and.to.be.a('object');
+ expect(payload.imp[10].video.placement).to.equal(4);
+ // outstream video; valid placement
+ expect(payload.imp[11]).to.not.have.property('banner');
+ expect(payload.imp[11]).to.have.property('video');
+ expect(payload.imp[11].video).to.exist.and.to.be.a('object');
+ expect(payload.imp[11].video.placement).to.equal(5);
+ // outstream video; undefined placement
+ expect(payload.imp[12]).to.not.have.property('banner');
+ expect(payload.imp[12]).to.have.property('video');
+ expect(payload.imp[12].video).to.exist.and.to.be.a('object');
+ expect(payload.imp[12].video.placement).to.equal(3);
+ // outstream video; invalid placement
+ expect(payload.imp[13]).to.not.have.property('banner');
+ expect(payload.imp[13]).to.have.property('video');
+ expect(payload.imp[13].video).to.exist.and.to.be.a('object');
+ expect(payload.imp[13].video.placement).to.equal(3);
});
it('should add tdid to the payload if included', function () {
@@ -460,6 +714,24 @@ describe('triplelift adapter', function () {
expect(payload.user).to.deep.equal({ext: {eids: [{source: 'criteo.com', uids: [{id, ext: {rtiPartner: 'criteoId'}}]}]}});
});
+ it('should add adqueryId to the payload if included', function () {
+ const id = '%7B%22qid%22%3A%229c985f8cc31d9b3c000d%22%7D';
+ bidRequests[0].userIdAsEids = [{ source: 'adquery.io', uids: [{ id }] }];
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ const payload = request.data;
+ expect(payload).to.exist;
+ expect(payload.user).to.deep.equal({ext: {eids: [{source: 'adquery.io', uids: [{id, ext: {rtiPartner: 'adquery.io'}}]}]}});
+ });
+
+ it('should add amxRtbId to the payload if included', function () {
+ const id = 'Ok9JQkBM-UFlAXEZQ-UUNBQlZOQzgrUFhW-UUNBQkRQTUBPQVpVWVxNXlZUUF9AUFhAUF9PXFY/';
+ bidRequests[0].userIdAsEids = [{ source: 'amxrtb.com', uids: [{ id }] }];
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ const payload = request.data;
+ expect(payload).to.exist;
+ expect(payload.user).to.deep.equal({ext: {eids: [{source: 'amxrtb.com', uids: [{id, ext: {rtiPartner: 'amxrtb.com'}}]}]}});
+ });
+
it('should add tdid, idl_env and criteoId to the payload if both are included', function () {
const tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598';
const idlEnvId = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI';
@@ -814,13 +1086,7 @@ describe('triplelift adapter', function () {
sens: sens,
}
}
- sandbox.stub(config, 'getConfig').callsFake(key => {
- const config = {
- ortb2
- };
- return utils.deepAccess(config, key);
- });
- const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, {...bidderRequest, ortb2});
const { data: payload } = request;
expect(payload.ext.fpd.user).to.not.exist;
expect(payload.ext.fpd.context.ext.data).to.haveOwnProperty('category');
@@ -833,6 +1099,68 @@ describe('triplelift adapter', function () {
expect(request.data.imp[0].fpd.context.data).to.haveOwnProperty('adUnitSpecificAttribute');
expect(request.data.imp[1].fpd).to.not.exist;
});
+ it('should send 1PlusX data as fpd if localStorage is available and no other fpd is defined', function() {
+ sandbox.stub(storage, 'getDataFromLocalStorage').callsFake(() => '{"kid":1,"s":"ySRdArquXuBolr/cVv0UNqrJhTO4QZsbNH/t+2kR3gXjbA==","t":"/yVtBrquXuBolr/cVv0UNtx1mssdLYeKFhWFI3Dq1dJnug=="}');
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.ext.fpd).to.deep.equal({
+ 'user': {
+ 'data': [
+ {
+ 'name': 'www.1plusx.com',
+ 'ext': {
+ 'kid': 1,
+ 's': 'ySRdArquXuBolr/cVv0UNqrJhTO4QZsbNH/t+2kR3gXjbA==',
+ 't': '/yVtBrquXuBolr/cVv0UNtx1mssdLYeKFhWFI3Dq1dJnug=='
+ }
+ }
+ ]
+ }
+ })
+ });
+ it('should append 1PlusX data to existing user.data entries if localStorage is available', function() {
+ bidderRequest.ortb2 = {
+ user: {
+ data: [
+ { name: 'dataprovider.com', ext: { segtax: 4 }, segment: [{ id: '1' }] }
+ ]
+ }
+ }
+ sandbox.stub(storage, 'getDataFromLocalStorage').callsFake(() => '{"kid":1,"s":"ySRdArquXuBolr/cVv0UNqrJhTO4QZsbNH/t+2kR3gXjbA==","t":"/yVtBrquXuBolr/cVv0UNtx1mssdLYeKFhWFI3Dq1dJnug=="}');
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.ext.fpd).to.deep.equal({
+ 'user': {
+ 'data': [
+ { 'name': 'dataprovider.com', 'ext': { 'segtax': 4 }, 'segment': [{ 'id': '1' }] },
+ {
+ 'name': 'www.1plusx.com',
+ 'ext': {
+ 'kid': 1,
+ 's': 'ySRdArquXuBolr/cVv0UNqrJhTO4QZsbNH/t+2kR3gXjbA==',
+ 't': '/yVtBrquXuBolr/cVv0UNtx1mssdLYeKFhWFI3Dq1dJnug=='
+ }
+ }
+ ]
+ }
+ })
+ });
+ it('should not append anything if getDataFromLocalStorage returns null', function() {
+ bidderRequest.ortb2 = {
+ user: {
+ data: [
+ { name: 'dataprovider.com', ext: { segtax: 4 }, segment: [{ id: '1' }] }
+ ]
+ }
+ }
+ sandbox.stub(storage, 'getDataFromLocalStorage').callsFake(() => null);
+ const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest);
+ expect(request.data.ext.fpd).to.deep.equal({
+ 'user': {
+ 'data': [
+ { 'name': 'dataprovider.com', 'ext': { 'segtax': 4 }, 'segment': [{ 'id': '1' }] },
+ ]
+ }
+ })
+ });
});
describe('interpretResponse', function () {
@@ -850,14 +1178,40 @@ describe('triplelift adapter', function () {
iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg',
tl_source: 'tlx',
advertiser_name: 'fake advertiser name',
- adomain: ['basspro.com', 'internetalerts.org']
+ adomain: ['basspro.com', 'internetalerts.org'],
+ media_type: 'banner'
},
{
imp_id: 1,
crid: '10092_76480_i2j6qm8u',
cpm: 9.99,
- ad: '
The Trade Desk',
- tlx_source: 'hdx'
+ ad: '
The Trade Desk',
+ tl_source: 'hdx',
+ media_type: 'video'
+ },
+ // video bid on banner+outstream request
+ {
+ imp_id: 2,
+ crid: '5989_33264_352817187',
+ cpm: 20,
+ ad: '
\n \n \t',
+ tl_source: 'hdx',
+ advertiser_name: 'zennioptical.com',
+ adomain: ['zennioptical.com'],
+ media_type: 'video'
+ },
+ // banner bid on banner+outstream request
+ {
+ imp_id: 3,
+ crid: '5989_33264_352817187',
+ cpm: 20,
+ width: 970,
+ height: 250,
+ ad: 'ad-markup',
+ tl_source: 'hdx',
+ advertiser_name: 'zennioptical.com',
+ adomain: ['zennioptical.com'],
+ media_type: 'banner'
}
]
}
@@ -883,13 +1237,13 @@ describe('triplelift adapter', function () {
]
}
},
- bidId: '30b31c1838de1e',
+ bidId: '30b31c1838de1e'
},
{
imp_id: 1,
crid: '10092_76480_i2j6qm8u',
cpm: 9.99,
- ad: 'The Trade Desk',
+ ad: 'The Trade Desk',
tlx_source: 'hdx',
mediaTypes: {
video: {
@@ -897,7 +1251,89 @@ describe('triplelift adapter', function () {
playerSize: [640, 480]
}
},
- bidId: '30b31c1838de1e',
+ bidId: '30b31c1838de1e'
+ },
+ // banner and outstream
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'testing_desktop_outstream',
+ floor: 1
+ },
+ nativeParams: {},
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [[640, 480]],
+ mimes: ['video/mp4'],
+ protocols: [1, 2, 3, 4, 5, 6, 7, 8],
+ playbackmethod: [2],
+ skip: 1
+ },
+ banner: {
+ sizes: [
+ [728, 90],
+ [970, 250],
+ [970, 90]
+ ]
+ },
+ native: {}
+ },
+ adUnitCode: 'video-outstream',
+ transactionId: '135061c3-f546-4e28-8a07-44c2fb58a958',
+ sizes: [
+ [728, 90],
+ [970, 250],
+ [970, 90]
+ ],
+ bidId: '73edc0ba8de203',
+ bidderRequestId: '3d81143328560b',
+ auctionId: 'f6427dc0-b954-4010-a76c-d498380796a2',
+ src: 'client',
+ bidRequestsCount: 2,
+ bidderRequestsCount: 2,
+ bidderWinsCount: 0
+ },
+ // banner and outstream
+ {
+ bidder: 'triplelift',
+ params: {
+ inventoryCode: 'testing_desktop_outstream',
+ floor: 1
+ },
+ nativeParams: {},
+ mediaTypes: {
+ video: {
+ context: 'outstream',
+ playerSize: [[640, 480]],
+ mimes: ['video/mp4'],
+ protocols: [1, 2, 3, 4, 5, 6, 7, 8],
+ playbackmethod: [2],
+ skip: 1
+ },
+ banner: {
+ sizes: [
+ [728, 90],
+ [970, 250],
+ [970, 90]
+ ]
+ },
+ native: {}
+ },
+ adUnitCode: 'video-outstream',
+ transactionId: '135061c3-f546-4e28-8a07-44c2fb58a958',
+ sizes: [
+ [728, 90],
+ [970, 250],
+ [970, 90]
+ ],
+ bidId: '73edc0ba8de203',
+ bidderRequestId: '3d81143328560b',
+ auctionId: 'f6427dc0-b954-4010-a76c-d498380796a2',
+ src: 'client',
+ bidRequestsCount: 2,
+ bidderRequestsCount: 2,
+ bidderWinsCount: 0
}
],
refererInfo: {
@@ -944,16 +1380,29 @@ describe('triplelift adapter', function () {
}
];
let result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest});
- expect(result).to.have.length(2);
+ expect(result).to.have.length(4);
expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
expect(Object.keys(result[1])).to.have.members(Object.keys(expectedResponse[1]));
expect(result[0].ttl).to.equal(300);
expect(result[1].ttl).to.equal(3600);
});
+ it('should identify format of bid and respond accordingly', function() {
+ let result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest});
+ expect(result[0].meta.mediaType).to.equal('native');
+ expect(result[1].mediaType).to.equal('video');
+ expect(result[1].meta.mediaType).to.equal('video');
+ // video bid on banner+outstream request
+ expect(result[2].mediaType).to.equal('video');
+ expect(result[2].meta.mediaType).to.equal('video');
+ expect(result[2].vastXml).to.include('aid=148508128401385324170&inv_code=testing_mobile_outstream');
+ // banner bid on banner+outstream request
+ expect(result[3].meta.mediaType).to.equal('banner');
+ })
+
it('should return multiple responses to support SRA', function () {
let result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest});
- expect(result).to.have.length(2);
+ expect(result).to.have.length(4);
});
it('should include the advertiser name in the meta field if available', function () {
diff --git a/test/spec/modules/truereachBidAdapter_spec.js b/test/spec/modules/truereachBidAdapter_spec.js
index 3c78c4b848d..cd7d0873569 100644
--- a/test/spec/modules/truereachBidAdapter_spec.js
+++ b/test/spec/modules/truereachBidAdapter_spec.js
@@ -83,7 +83,7 @@ describe('truereachBidAdapterTests', function () {
});
describe('user_sync', function() {
- const user_sync_url = 'http://ads.momagic.com/jsp/usersync.jsp';
+ const user_sync_url = 'https://ads-sg.momagic.com/jsp/usersync.jsp';
it('register_iframe_pixel_if_iframeEnabled_is_true', function() {
let syncs = spec.getUserSyncs(
{iframeEnabled: true}
diff --git a/test/spec/modules/trustpidSystem_spec.js b/test/spec/modules/trustpidSystem_spec.js
index a3e41d7a58e..38e861d977f 100644
--- a/test/spec/modules/trustpidSystem_spec.js
+++ b/test/spec/modules/trustpidSystem_spec.js
@@ -22,14 +22,6 @@ describe('trustpid System', () => {
});
describe('trustpid getId()', () => {
- before(() => {
- window.FC_CONF = {
- TELCO_ACRONYM: {
- 'domain.with.acronym': 'acronymValue',
- }
- };
- });
-
afterEach(() => {
storage.removeDataFromLocalStorage(connectDataKey);
storage.removeDataFromLocalStorage(connectDomainKey);
@@ -52,7 +44,7 @@ describe('trustpid System', () => {
it('tests if localstorage & JSON works properly ', () => {
const idGraph = {
'domain': 'domainValue',
- 'umid': 'umidValue',
+ 'atid': 'atidValue',
};
storage.setDataInLocalStorage(connectDataKey, JSON.stringify(getStorageData(idGraph)));
expect(JSON.parse(storage.getDataFromLocalStorage(connectDataKey))).to.have.property('connectId');
@@ -61,7 +53,7 @@ describe('trustpid System', () => {
it('returns {callback: func} if domains don\'t match', () => {
const idGraph = {
'domain': 'domainValue',
- 'umid': 'umidValue',
+ 'atid': 'atidValue',
};
storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('differentDomainValue'));
storage.setDataInLocalStorage(connectDataKey, JSON.stringify(getStorageData(idGraph)));
@@ -70,33 +62,33 @@ describe('trustpid System', () => {
it('returns {id: {trustpid: data.trustpid}} if we have the right data stored in the localstorage ', () => {
const idGraph = {
- 'domain': 'domain.with.acronym',
- 'umid': 'umidValue',
+ 'domain': 'test.domain',
+ 'atid': 'atidValue',
};
- storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('domain.with.acronym'));
+ storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('test.domain'));
storage.setDataInLocalStorage(connectDataKey, JSON.stringify(getStorageData(idGraph)));
const response = trustpidSubmodule.getId();
expect(response).to.have.property('id');
expect(response.id).to.have.property('trustpid');
- expect(response.id.trustpid).to.be.equal('umidValue-acronymValue');
+ expect(response.id.trustpid).to.be.equal('atidValue');
});
it('returns {trustpid: data.trustpid} if we have the right data stored in the localstorage right after the callback is called', (done) => {
const idGraph = {
- 'domain': 'domain.with.acronym',
- 'umid': 'umidValue',
+ 'domain': 'test.domain',
+ 'atid': 'atidValue',
};
const response = trustpidSubmodule.getId();
expect(response).to.have.property('callback');
expect(response.callback.toString()).contain('result(callback)');
if (typeof response.callback === 'function') {
- storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('domain.with.acronym'));
+ storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('test.domain'));
storage.setDataInLocalStorage(connectDataKey, JSON.stringify(getStorageData(idGraph)));
response.callback(function (result) {
expect(result).to.not.be.null;
expect(result).to.have.property('trustpid');
- expect(result.trustpid).to.be.equal('umidValue-acronymValue');
+ expect(result.trustpid).to.be.equal('atidValue');
done()
})
}
@@ -104,8 +96,8 @@ describe('trustpid System', () => {
it('returns null if domains don\'t match', (done) => {
const idGraph = {
- 'domain': 'domain.with.acronym',
- 'umid': 'umidValue',
+ 'domain': 'test.domain',
+ 'atid': 'atidValue',
};
storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('differentDomainValue'));
storage.setDataInLocalStorage(connectDataKey, JSON.stringify(getStorageData(idGraph)));
@@ -127,8 +119,8 @@ describe('trustpid System', () => {
it('returns {trustpid: data.trustpid} if we have the right data stored in the localstorage right after 500ms delay', (done) => {
const idGraph = {
- 'domain': 'domain.with.acronym',
- 'umid': 'umidValue',
+ 'domain': 'test.domain',
+ 'atid': 'atidValue',
};
const response = trustpidSubmodule.getId();
@@ -137,13 +129,13 @@ describe('trustpid System', () => {
if (typeof response.callback === 'function') {
setTimeout(() => {
- storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('domain.with.acronym'));
+ storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('test.domain'));
storage.setDataInLocalStorage(connectDataKey, JSON.stringify(getStorageData(idGraph)));
}, 500);
response.callback(function (result) {
expect(result).to.not.be.null;
expect(result).to.have.property('trustpid');
- expect(result.trustpid).to.be.equal('umidValue-acronymValue');
+ expect(result.trustpid).to.be.equal('atidValue');
done()
})
}
@@ -151,8 +143,8 @@ describe('trustpid System', () => {
it('returns null if we have the data stored in the localstorage after 500ms delay and the max (waiting) delay is only 200ms ', (done) => {
const idGraph = {
- 'domain': 'domain.with.acronym',
- 'umid': 'umidValue',
+ 'domain': 'test.domain',
+ 'atid': 'atidValue',
};
const response = trustpidSubmodule.getId({params: {maxDelayTime: 200}});
@@ -161,7 +153,7 @@ describe('trustpid System', () => {
if (typeof response.callback === 'function') {
setTimeout(() => {
- storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('domain.with.acronym'));
+ storage.setDataInLocalStorage(connectDomainKey, JSON.stringify('test.domain'));
storage.setDataInLocalStorage(connectDataKey, JSON.stringify(getStorageData(idGraph)));
}, 500);
response.callback(function (result) {
@@ -202,17 +194,7 @@ describe('trustpid System', () => {
});
});
- describe('trustpid messageHandler for acronyms', () => {
- before(() => {
- window.FC_CONF = {
- TELCO_ACRONYM: {
- 'domain1': 'abcd',
- 'domain2': 'efgh',
- 'domain3': 'ijkl',
- }
- };
- });
-
+ describe('trustpid messageHandler', () => {
afterEach(() => {
storage.removeDataFromLocalStorage(connectDataKey);
storage.removeDataFromLocalStorage(connectDomainKey);
@@ -223,16 +205,16 @@ describe('trustpid System', () => {
})
const domains = [
- {domain: 'domain1', acronym: 'abcd'},
- {domain: 'domain2', acronym: 'efgh'},
- {domain: 'domain3', acronym: 'ijkl'},
+ 'domain1',
+ 'domain2',
+ 'domain3',
];
- domains.forEach(({domain, acronym}) => {
- it(`correctly sets trustpid value and acronym to ${acronym} for ${domain}`, (done) => {
+ domains.forEach(domain => {
+ it(`correctly sets trustpid value for domain name ${domain}`, (done) => {
const idGraph = {
'domain': domain,
- 'umid': 'umidValue',
+ 'atid': 'atidValue',
};
storage.setDataInLocalStorage(connectDomainKey, JSON.stringify(domain));
@@ -247,7 +229,7 @@ describe('trustpid System', () => {
const response = trustpidSubmodule.getId();
expect(response).to.have.property('id');
expect(response.id).to.have.property('trustpid');
- expect(response.id.trustpid).to.be.equal(`umidValue-${acronym}`);
+ expect(response.id.trustpid).to.be.equal('atidValue');
done();
});
});
diff --git a/test/spec/modules/trustxBidAdapter_spec.js b/test/spec/modules/trustxBidAdapter_spec.js
deleted file mode 100644
index b34813948fc..00000000000
--- a/test/spec/modules/trustxBidAdapter_spec.js
+++ /dev/null
@@ -1,1372 +0,0 @@
-import { expect } from 'chai';
-import { spec } from 'modules/trustxBidAdapter.js';
-import { newBidder } from 'src/adapters/bidderFactory.js';
-import { config } from 'src/config.js';
-
-describe('TrustXAdapter', function () {
- const adapter = newBidder(spec);
-
- describe('inherited functions', function () {
- it('exists and is a function', function () {
- expect(adapter.callBids).to.exist.and.to.be.a('function');
- });
- });
-
- describe('isBidRequestValid', function () {
- let bid = {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '44'
- },
- 'adUnitCode': 'adunit-code',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '1d1a030790a475',
- };
-
- it('should return true when required params found', function () {
- expect(spec.isBidRequestValid(bid)).to.equal(true);
- });
-
- it('should return false when required params are not passed', function () {
- let bid = Object.assign({}, bid);
- delete bid.params;
- bid.params = {
- 'uid': 0
- };
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
- });
-
- describe('buildRequests', function () {
- function parseRequest(data) {
- return JSON.parse(data);
- }
- const bidderRequest = {
- refererInfo: {referer: 'https://example.com'},
- bidderRequestId: '22edbae2733bf6',
- auctionId: '9e2dfbfe-00c7-4f5e-9850-4044df3229c7',
- timeout: 3000
- };
- const referrer = encodeURIComponent(bidderRequest.refererInfo.referer);
-
- let bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43',
- 'bidFloor': 1.25,
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'mediaTypes': {
- 'banner': {
- 'sizes': [[300, 250], [300, 600]]
- }
- },
- 'bidId': '42dbe3a7168a6a',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '44',
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '30b31c1838de1e',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '45',
- },
- 'adUnitCode': 'adunit-code-2',
- 'sizes': [[728, 90]],
- 'mediaTypes': {
- 'video': {
- 'playerSize': [[400, 600]],
- 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg']
- }
- },
- 'bidId': '3150ccb55da321',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '41',
- },
- 'adUnitCode': 'adunit-code-2',
- 'sizes': [[728, 90]],
- 'mediaTypes': {
- 'video': {
- 'playerSize': [[400, 600]],
- 'protocols': [1, 2, 3]
- },
- 'banner': {
- 'sizes': [[728, 90]]
- }
- },
- 'bidId': '3150ccb55da321',
- 'bidderRequestId': '22edbae2733bf6',
- 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7',
- }
- ];
-
- it('should attach valid params to the tag', function () {
- const request = spec.buildRequests([bidRequests[0]], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.deep.equal({
- 'id': bidderRequest.bidderRequestId,
- 'site': {
- 'page': referrer
- },
- 'tmax': bidderRequest.timeout,
- 'source': {
- 'tid': bidderRequest.auctionId,
- 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'}
- },
- 'imp': [{
- 'id': bidRequests[0].bidId,
- 'tagid': bidRequests[0].params.uid,
- 'ext': {'divid': bidRequests[0].adUnitCode},
- 'bidfloor': bidRequests[0].params.bidFloor,
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }]
- });
- });
-
- it('make possible to process request without mediaTypes', function () {
- const request = spec.buildRequests([bidRequests[0], bidRequests[1]], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.deep.equal({
- 'id': bidderRequest.bidderRequestId,
- 'site': {
- 'page': referrer
- },
- 'tmax': bidderRequest.timeout,
- 'source': {
- 'tid': bidderRequest.auctionId,
- 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'}
- },
- 'imp': [{
- 'id': bidRequests[0].bidId,
- 'tagid': bidRequests[0].params.uid,
- 'ext': {'divid': bidRequests[0].adUnitCode},
- 'bidfloor': bidRequests[0].params.bidFloor,
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }, {
- 'id': bidRequests[1].bidId,
- 'tagid': bidRequests[1].params.uid,
- 'ext': {'divid': bidRequests[1].adUnitCode},
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }]
- });
- });
-
- it('should attach valid params to the video tag', function () {
- const request = spec.buildRequests(bidRequests.slice(0, 3), bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.deep.equal({
- 'id': bidderRequest.bidderRequestId,
- 'site': {
- 'page': referrer
- },
- 'tmax': bidderRequest.timeout,
- 'source': {
- 'tid': bidderRequest.auctionId,
- 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'}
- },
- 'imp': [{
- 'id': bidRequests[0].bidId,
- 'tagid': bidRequests[0].params.uid,
- 'ext': {'divid': bidRequests[0].adUnitCode},
- 'bidfloor': bidRequests[0].params.bidFloor,
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }, {
- 'id': bidRequests[1].bidId,
- 'tagid': bidRequests[1].params.uid,
- 'ext': {'divid': bidRequests[1].adUnitCode},
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }, {
- 'id': bidRequests[2].bidId,
- 'tagid': bidRequests[2].params.uid,
- 'ext': {'divid': bidRequests[2].adUnitCode},
- 'video': {
- 'w': 400,
- 'h': 600,
- 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg']
- }
- }]
- });
- });
-
- it('should support mixed mediaTypes', function () {
- const request = spec.buildRequests(bidRequests, bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.deep.equal({
- 'id': bidderRequest.bidderRequestId,
- 'site': {
- 'page': referrer
- },
- 'tmax': bidderRequest.timeout,
- 'source': {
- 'tid': bidderRequest.auctionId,
- 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'}
- },
- 'imp': [{
- 'id': bidRequests[0].bidId,
- 'tagid': bidRequests[0].params.uid,
- 'ext': {'divid': bidRequests[0].adUnitCode},
- 'bidfloor': bidRequests[0].params.bidFloor,
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }, {
- 'id': bidRequests[1].bidId,
- 'tagid': bidRequests[1].params.uid,
- 'ext': {'divid': bidRequests[1].adUnitCode},
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }, {
- 'id': bidRequests[2].bidId,
- 'tagid': bidRequests[2].params.uid,
- 'ext': {'divid': bidRequests[2].adUnitCode},
- 'video': {
- 'w': 400,
- 'h': 600,
- 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'],
- }
- }, {
- 'id': bidRequests[3].bidId,
- 'tagid': bidRequests[3].params.uid,
- 'ext': {'divid': bidRequests[3].adUnitCode},
- 'banner': {
- 'w': 728,
- 'h': 90,
- 'format': [{'w': 728, 'h': 90}]
- },
- 'video': {
- 'w': 400,
- 'h': 600,
- 'protocols': [1, 2, 3]
- }
- }]
- });
- });
-
- it('if gdprConsent is present payload must have gdpr params', function () {
- const gdprBidderRequest = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest);
- const request = spec.buildRequests(bidRequests, gdprBidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.have.property('user');
- expect(payload.user).to.have.property('ext');
- expect(payload.user.ext).to.have.property('consent', 'AAA');
- expect(payload).to.have.property('regs');
- expect(payload.regs).to.have.property('ext');
- expect(payload.regs.ext).to.have.property('gdpr', 1);
- });
-
- it('if usPrivacy is present payload must have us_privacy param', function () {
- const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest);
- const request = spec.buildRequests(bidRequests, bidderRequestWithUSP);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.have.property('regs');
- expect(payload.regs).to.have.property('ext');
- expect(payload.regs.ext).to.have.property('us_privacy', '1YNN');
- });
-
- it('if userId is present payload must have user.ext param with right keys', function () {
- const eids = [
- {
- source: 'pubcid.org',
- uids: [{
- id: 'some-random-id-value',
- atype: 1
- }]
- },
- {
- source: 'adserver.org',
- uids: [{
- id: 'some-random-id-value',
- atype: 1,
- ext: {
- rtiPartner: 'TDID'
- }
- }]
- }
- ];
- const bidRequestsWithUserIds = bidRequests.map((bid) => {
- return Object.assign({
- userIdAsEids: eids
- }, bid);
- });
- const request = spec.buildRequests(bidRequestsWithUserIds, bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.have.property('user');
- expect(payload.user).to.have.property('ext');
- expect(payload.user.ext.eids).to.deep.equal(eids);
- });
-
- it('if schain is present payload must have source.ext.schain param', function () {
- const schain = {
- complete: 1,
- nodes: [
- {
- asi: 'indirectseller.com',
- sid: '00001',
- hp: 1
- }
- ]
- };
- const bidRequestsWithSChain = bidRequests.map((bid) => {
- return Object.assign({
- schain: schain
- }, bid);
- });
- const request = spec.buildRequests(bidRequestsWithSChain, bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.have.property('source');
- expect(payload.source).to.have.property('ext');
- expect(payload.source.ext).to.have.property('schain');
- expect(payload.source.ext.schain).to.deep.equal(schain);
- });
-
- it('if content and segment is present in jwTargeting, payload must have right params', function () {
- const jsContent = {id: 'test_jw_content_id'};
- const jsSegments = ['test_seg_1', 'test_seg_2'];
- const bidRequestsWithJwTargeting = bidRequests.map((bid) => {
- return Object.assign({
- rtd: {
- jwplayer: {
- targeting: {
- segments: jsSegments,
- content: jsContent
- }
- }
- }
- }, bid);
- });
- const request = spec.buildRequests(bidRequestsWithJwTargeting, bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.have.property('user');
- expect(payload.user.data).to.deep.equal([{
- name: 'iow_labs_pub_data',
- segment: [
- {name: 'jwpseg', value: jsSegments[0]},
- {name: 'jwpseg', value: jsSegments[1]}
- ]
- }]);
- expect(payload).to.have.property('site');
- expect(payload.site.content).to.deep.equal(jsContent);
- });
-
- it('should have user.data filled from config ortb2.user.data', function () {
- const userData = [
- {
- name: 'someName',
- segment: [1, 2, { anyKey: 'anyVal' }, 'segVal', { id: 'segId' }, { value: 'segValue' }, { id: 'segId2', name: 'segName' }]
- },
- {
- name: 'permutive.com',
- segment: [1, 2, 'segVal', { id: 'segId' }, { anyKey: 'anyVal' }, { value: 'segValue' }, { id: 'segId2', name: 'segName' }]
- },
- {
- someKey: 'another data'
- }
- ];
-
- const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
- arg => arg === 'ortb2.user.data' ? userData : null);
- const request = spec.buildRequests([bidRequests[0]], bidderRequest);
- const payload = parseRequest(request.data);
- expect(payload.user.data).to.deep.equal(userData);
- getConfigStub.restore();
- });
-
- it('should have right value in user.data when jwpsegments are present', function () {
- const userData = [
- {
- name: 'someName',
- segment: [1, 2, { anyKey: 'anyVal' }, 'segVal', { id: 'segId' }, { value: 'segValue' }, { id: 'segId2', name: 'segName' }]
- },
- {
- name: 'permutive.com',
- segment: [1, 2, 'segVal', { id: 'segId' }, { anyKey: 'anyVal' }, { value: 'segValue' }, { id: 'segId2', name: 'segName' }]
- },
- {
- someKey: 'another data'
- }
- ];
- const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
- arg => arg === 'ortb2.user.data' ? userData : null);
-
- const jsContent = {id: 'test_jw_content_id'};
- const jsSegments = ['test_seg_1', 'test_seg_2'];
- const bidRequestsWithJwTargeting = Object.assign({}, bidRequests[0], {
- rtd: {
- jwplayer: {
- targeting: {
- segments: jsSegments,
- content: jsContent
- }
- }
- }
- });
- const request = spec.buildRequests([bidRequestsWithJwTargeting], bidderRequest);
- const payload = parseRequest(request.data);
- expect(payload.user.data).to.deep.equal([{
- name: 'iow_labs_pub_data',
- segment: [
- {name: 'jwpseg', value: jsSegments[0]},
- {name: 'jwpseg', value: jsSegments[1]}
- ]
- }, ...userData]);
- getConfigStub.restore();
- });
-
- it('should contain the keyword values if it present in ortb2.(site/user)', function () {
- const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
- arg => arg === 'ortb2.user' ? {'keywords': 'foo,any'} : (arg === 'ortb2.site' ? {'keywords': 'bar'} : null));
- const keywords = {
- 'site': {
- 'somePublisher': [
- {
- 'name': 'someName',
- 'brandsafety': ['disaster'],
- 'topic': ['stress', 'fear']
- }
- ]
- },
- 'user': {
- 'formatedPublisher': [
- {
- 'name': 'fomatedName',
- 'segments': [
- { 'name': 'segName1', 'value': 'segVal1' },
- { 'name': 'segName2', 'value': 'segVal2' }
- ]
- }
- ]
- }
- };
- const bidRequestWithKW = { ...bidRequests[0], params: { ...bidRequests[0].params, keywords } }
- const request = spec.buildRequests([bidRequestWithKW], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.ext.keywords).to.deep.equal({
- 'site': {
- 'somePublisher': [
- {
- 'name': 'someName',
- 'segments': [
- { 'name': 'brandsafety', 'value': 'disaster' },
- { 'name': 'topic', 'value': 'stress' },
- { 'name': 'topic', 'value': 'fear' }
- ]
- }
- ],
- 'ortb2': [
- {
- 'name': 'keywords',
- 'segments': [
- { 'name': 'keywords', 'value': 'bar' }
- ]
- }
- ]
- },
- 'user': {
- 'formatedPublisher': [
- {
- 'name': 'fomatedName',
- 'segments': [
- { 'name': 'segName1', 'value': 'segVal1' },
- { 'name': 'segName2', 'value': 'segVal2' }
- ]
- }
- ],
- 'ortb2': [
- {
- 'name': 'keywords',
- 'segments': [
- { 'name': 'keywords', 'value': 'foo' },
- { 'name': 'keywords', 'value': 'any' }
- ]
- }
- ]
- }
- });
- getConfigStub.restore();
- });
-
- it('should be right tmax when timeout in config is less then timeout in bidderRequest', function() {
- const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
- arg => arg === 'bidderTimeout' ? 2000 : null);
- const request = spec.buildRequests([bidRequests[0]], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.tmax).to.equal(2000);
- getConfigStub.restore();
- });
- it('should be right tmax when timeout in bidderRequest is less then timeout in config', function() {
- const getConfigStub = sinon.stub(config, 'getConfig').callsFake(
- arg => arg === 'bidderTimeout' ? 5000 : null);
- const request = spec.buildRequests([bidRequests[0]], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.tmax).to.equal(3000);
- getConfigStub.restore();
- });
- it('should contain imp[].ext.data.adserver if available', function() {
- const ortb2Imp = [{
- ext: {
- data: {
- adserver: {
- name: 'ad_server_name',
- adslot: '/111111/slot'
- },
- pbadslot: '/111111/slot'
- }
- }
- }, {
- ext: {
- data: {
- adserver: {
- name: 'ad_server_name',
- adslot: '/222222/slot'
- },
- pbadslot: '/222222/slot'
- }
- }
- }];
- const bidRequestsWithOrtb2Imp = bidRequests.slice(0, 3).map((bid, ind) => {
- return Object.assign(ortb2Imp[ind] ? { ortb2Imp: ortb2Imp[ind] } : {}, bid);
- });
- const request = spec.buildRequests(bidRequestsWithOrtb2Imp, bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.imp[0].ext).to.deep.equal({
- divid: bidRequests[0].adUnitCode,
- data: ortb2Imp[0].ext.data,
- gpid: ortb2Imp[0].ext.data.adserver.adslot
- });
- expect(payload.imp[1].ext).to.deep.equal({
- divid: bidRequests[1].adUnitCode,
- data: ortb2Imp[1].ext.data,
- gpid: ortb2Imp[1].ext.data.adserver.adslot
- });
- expect(payload.imp[2].ext).to.deep.equal({
- divid: bidRequests[2].adUnitCode
- });
- });
- it('should contain imp[].instl if available', function() {
- const ortb2Imp = [{
- instl: 1
- }, {
- instl: 2,
- ext: {
- data: {
- adserver: {
- name: 'ad_server_name',
- adslot: '/222222/slot'
- },
- pbadslot: '/222222/slot'
- }
- }
- }];
- const bidRequestsWithOrtb2Imp = bidRequests.slice(0, 3).map((bid, ind) => {
- return Object.assign(ortb2Imp[ind] ? { ortb2Imp: ortb2Imp[ind] } : {}, bid);
- });
- const request = spec.buildRequests(bidRequestsWithOrtb2Imp, bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.imp[0].instl).to.equal(1);
- expect(payload.imp[1].ext).to.deep.equal({
- divid: bidRequests[1].adUnitCode,
- data: ortb2Imp[1].ext.data,
- gpid: ortb2Imp[1].ext.data.adserver.adslot
- });
- expect(payload.imp[1].instl).to.equal(2);
- expect(payload.imp[2].ext).to.deep.equal({
- divid: bidRequests[2].adUnitCode
- });
- expect(payload.imp[2].instl).to.be.undefined;
- });
- it('all id like request fields must be a string', function () {
- const bidderRequestWithNumId = Object.assign({}, bidderRequest, { bidderRequestId: 123123, auctionId: 345345543 });
-
- let bidRequestWithNumId = {
- 'bidder': 'trustx',
- 'params': {
- 'uid': 43,
- },
- 'adUnitCode': 111111,
- 'sizes': [[300, 250], [300, 600]],
- 'mediaTypes': {
- 'banner': {
- 'sizes': [[300, 250], [300, 600]]
- }
- },
- 'bidId': 23423423,
- 'bidderRequestId': 123123,
- 'auctionId': 345345543,
- };
-
- const request = spec.buildRequests([bidRequestWithNumId], bidderRequestWithNumId);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload).to.deep.equal({
- 'id': '123123',
- 'site': {
- 'page': referrer
- },
- 'tmax': bidderRequest.timeout,
- 'source': {
- 'tid': '345345543',
- 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'}
- },
- 'imp': [{
- 'id': '23423423',
- 'tagid': '43',
- 'ext': {'divid': '111111'},
- 'banner': {
- 'w': 300,
- 'h': 250,
- 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}]
- }
- }]
- });
- });
-
- describe('floorModule', function () {
- const floorTestData = {
- 'currency': 'USD',
- 'floor': 1.50
- };
- const bidRequest = Object.assign({
- getFloor: (_) => {
- return floorTestData;
- }
- }, bidRequests[1]);
- it('should return the value from getFloor if present', function () {
- const request = spec.buildRequests([bidRequest], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.imp[0].bidfloor).to.equal(floorTestData.floor);
- });
- it('should return the getFloor.floor value if it is greater than bidfloor', function () {
- const bidfloor = 0.80;
- const bidRequestsWithFloor = { ...bidRequest };
- bidRequestsWithFloor.params = Object.assign({bidFloor: bidfloor}, bidRequestsWithFloor.params);
- const request = spec.buildRequests([bidRequestsWithFloor], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.imp[0].bidfloor).to.equal(floorTestData.floor);
- });
- it('should return the bidfloor value if it is greater than getFloor.floor', function () {
- const bidfloor = 1.80;
- const bidRequestsWithFloor = { ...bidRequest };
- bidRequestsWithFloor.params = Object.assign({bidFloor: bidfloor}, bidRequestsWithFloor.params);
- const request = spec.buildRequests([bidRequestsWithFloor], bidderRequest);
- expect(request.data).to.be.an('string');
- const payload = parseRequest(request.data);
- expect(payload.imp[0].bidfloor).to.equal(bidfloor);
- });
- });
- });
-
- describe('interpretResponse', function () {
- const responses = [
- {'bid': [{'impid': '659423fff799cb', 'price': 1.15, 'adm': 'test content 1
', 'auid': 43, 'h': 250, 'w': 300, 'adomain': ['somedomain.com']}], 'seat': '1'},
- {'bid': [{'impid': '4dff80cc4ee346', 'price': 0.5, 'adm': 'test content 2
', 'auid': 44, 'h': 600, 'w': 300}], 'seat': '1'},
- {'bid': [{'impid': '5703af74d0472a', 'price': 0.15, 'adm': 'test content 3
', 'auid': 43, 'h': 90, 'w': 728}], 'seat': '1'},
- {'bid': [{'impid': '659423faac49cb', 'price': 0, 'auid': 45, 'h': 250, 'w': 300}], 'seat': '1'},
- {'bid': [{'price': 0, 'adm': 'test content 5
', 'h': 250, 'w': 300}], 'seat': '1'},
- undefined,
- {'bid': [], 'seat': '1'},
- {'seat': '1'},
- ];
-
- it('should get correct bid response', function () {
- const bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '659423fff799cb',
- 'bidderRequestId': '5f2009617a7c0a',
- 'auctionId': '1cbd2feafe5e8b',
- }
- ];
- const request = spec.buildRequests(bidRequests);
- const expectedResponse = [
- {
- 'requestId': '659423fff799cb',
- 'cpm': 1.15,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 300,
- 'height': 250,
- 'ad': 'test content 1
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': ['somedomain.com']
- },
- }
- ];
-
- const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request);
- expect(result).to.deep.equal(expectedResponse);
- });
-
- it('should get correct multi bid response', function () {
- const bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '659423fff799cb',
- 'bidderRequestId': '2c2bb1972df9a',
- 'auctionId': '1fa09aee5c8c99',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '44'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '4dff80cc4ee346',
- 'bidderRequestId': '2c2bb1972df9a',
- 'auctionId': '1fa09aee5c8c99',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-2',
- 'sizes': [[728, 90]],
- 'bidId': '5703af74d0472a',
- 'bidderRequestId': '2c2bb1972df9a',
- 'auctionId': '1fa09aee5c8c99',
- }
- ];
- const request = spec.buildRequests(bidRequests);
- const expectedResponse = [
- {
- 'requestId': '659423fff799cb',
- 'cpm': 1.15,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 300,
- 'height': 250,
- 'ad': 'test content 1
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': ['somedomain.com']
- },
- },
- {
- 'requestId': '4dff80cc4ee346',
- 'cpm': 0.5,
- 'creativeId': 44,
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'ad': 'test content 2
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- },
- {
- 'requestId': '5703af74d0472a',
- 'cpm': 0.15,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 728,
- 'height': 90,
- 'ad': 'test content 3
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- }
- ];
-
- const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request);
- expect(result).to.deep.equal(expectedResponse);
- });
-
- it('handles wrong and nobid responses', function () {
- const bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '45'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '300bfeb0d7190gf',
- 'bidderRequestId': '2c2bb1972d23af',
- 'auctionId': '1fa09aee5c84d34',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '46'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '300bfeb0d71321',
- 'bidderRequestId': '2c2bb1972d23af',
- 'auctionId': '1fa09aee5c84d34',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '50'
- },
- 'adUnitCode': 'adunit-code-2',
- 'sizes': [[728, 90]],
- 'bidId': '300bfeb0d7183bb',
- 'bidderRequestId': '2c2bb1972d23af',
- 'auctionId': '1fa09aee5c84d34',
- }
- ];
- const request = spec.buildRequests(bidRequests);
- const result = spec.interpretResponse({'body': {'seatbid': responses.slice(3)}}, request);
- expect(result.length).to.equal(0);
- });
-
- it('complicated case', function () {
- const fullResponse = [
- {'bid': [{'impid': '2164be6358b9', 'price': 1.15, 'adm': 'test content 1
', 'auid': 43, 'h': 250, 'w': 300}], 'seat': '1'},
- {'bid': [{'impid': '4e111f1b66e4', 'price': 0.5, 'adm': 'test content 2
', 'auid': 44, 'h': 600, 'w': 300}], 'seat': '1'},
- {'bid': [{'impid': '26d6f897b516', 'price': 0.15, 'adm': 'test content 3
', 'auid': 43, 'h': 90, 'w': 728}], 'seat': '1'},
- {'bid': [{'impid': '326bde7fbf69', 'price': 0.15, 'adm': 'test content 4
', 'auid': 43, 'h': 600, 'w': 300}], 'seat': '1'},
- {'bid': [{'impid': '1751cd90161', 'price': 0.5, 'adm': 'test content 5
', 'auid': 44, 'h': 600, 'w': 350}], 'seat': '1'},
- ];
- const bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '2164be6358b9',
- 'bidderRequestId': '106efe3247',
- 'auctionId': '32a1f276cb87cb8',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '326bde7fbf69',
- 'bidderRequestId': '106efe3247',
- 'auctionId': '32a1f276cb87cb8',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '44'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '4e111f1b66e4',
- 'bidderRequestId': '106efe3247',
- 'auctionId': '32a1f276cb87cb8',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-2',
- 'sizes': [[728, 90]],
- 'bidId': '26d6f897b516',
- 'bidderRequestId': '106efe3247',
- 'auctionId': '32a1f276cb87cb8',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '44'
- },
- 'adUnitCode': 'adunit-code-2',
- 'sizes': [[728, 90]],
- 'bidId': '1751cd90161',
- 'bidderRequestId': '106efe3247',
- 'auctionId': '32a1f276cb87cb8',
- }
- ];
- const request = spec.buildRequests(bidRequests);
- const expectedResponse = [
- {
- 'requestId': '2164be6358b9',
- 'cpm': 1.15,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 300,
- 'height': 250,
- 'ad': 'test content 1
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- },
- {
- 'requestId': '4e111f1b66e4',
- 'cpm': 0.5,
- 'creativeId': 44,
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'ad': 'test content 2
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- },
- {
- 'requestId': '26d6f897b516',
- 'cpm': 0.15,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 728,
- 'height': 90,
- 'ad': 'test content 3
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- },
- {
- 'requestId': '326bde7fbf69',
- 'cpm': 0.15,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'ad': 'test content 4
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- },
- {
- 'requestId': '1751cd90161',
- 'cpm': 0.5,
- 'creativeId': 44,
- 'dealId': undefined,
- 'width': 350,
- 'height': 600,
- 'ad': 'test content 5
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- }
- ];
-
- const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request);
- expect(result).to.deep.equal(expectedResponse);
- });
-
- it('dublicate uids and sizes in one slot', function () {
- const fullResponse = [
- {'bid': [{'impid': '5126e301f4be', 'price': 1.15, 'adm': 'test content 1
', 'auid': 43, 'h': 250, 'w': 300}], 'seat': '1'},
- {'bid': [{'impid': '57b2ebe70e16', 'price': 0.5, 'adm': 'test content 2
', 'auid': 43, 'h': 250, 'w': 300}], 'seat': '1'},
- ];
- const bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '5126e301f4be',
- 'bidderRequestId': '171c5405a390',
- 'auctionId': '35bcbc0f7e79c',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '57b2ebe70e16',
- 'bidderRequestId': '171c5405a390',
- 'auctionId': '35bcbc0f7e79c',
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '43'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '225fcd44b18c',
- 'bidderRequestId': '171c5405a390',
- 'auctionId': '35bcbc0f7e79c',
- }
- ];
- const request = spec.buildRequests(bidRequests);
- const expectedResponse = [
- {
- 'requestId': '5126e301f4be',
- 'cpm': 1.15,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 300,
- 'height': 250,
- 'ad': 'test content 1
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- },
- {
- 'requestId': '57b2ebe70e16',
- 'cpm': 0.5,
- 'creativeId': 43,
- 'dealId': undefined,
- 'width': 300,
- 'height': 250,
- 'ad': 'test content 2
',
- 'currency': 'USD',
- 'mediaType': 'banner',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- }
- ];
-
- const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request);
- expect(result).to.deep.equal(expectedResponse);
- });
- });
-
- it('should get correct video bid response', function () {
- const bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '50'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '57dfefb80eca',
- 'bidderRequestId': '20394420a762a2',
- 'auctionId': '140132d07b031',
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
- }
- }
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '51'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': 'e893c787c22dd',
- 'bidderRequestId': '20394420a762a2',
- 'auctionId': '140132d07b031',
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
- }
- }
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '52'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '23312a43bc42',
- 'bidderRequestId': '20394420a762a2',
- 'auctionId': '140132d07b031',
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
- }
- }
- }
- ];
- const response = [
- {'bid': [{'impid': '57dfefb80eca', 'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 50, content_type: 'video', w: 300, h: 600}], 'seat': '2'},
- {'bid': [{'impid': '5126e301f4be', 'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 51, content_type: 'video'}], 'seat': '2'},
- {'bid': [{'impid': '23312a43bc42', 'price': 2.00, 'nurl': 'https://some_test_vast_url.com', 'auid': 52, content_type: 'video', w: 300, h: 600}], 'seat': '2'},
- ];
- const request = spec.buildRequests(bidRequests);
- const expectedResponse = [
- {
- 'requestId': '57dfefb80eca',
- 'cpm': 1.15,
- 'creativeId': 50,
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- 'vastXml': '\n<\/Ad>\n<\/VAST>',
- 'adResponse': {
- 'content': '\n<\/Ad>\n<\/VAST>'
- }
- },
- {
- 'requestId': '23312a43bc42',
- 'cpm': 2.00,
- 'creativeId': 52,
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- 'vastUrl': 'https://some_test_vast_url.com',
- },
- ];
-
- const result = spec.interpretResponse({'body': {'seatbid': response}}, request);
- expect(result).to.deep.equal(expectedResponse);
- });
-
- it('should have right renderer in the bid response', function () {
- const spySetRenderer = sinon.spy();
- const stubRenderer = {
- setRender: spySetRenderer
- };
- const spyRendererInstall = sinon.spy(function() { return stubRenderer; });
- const stubRendererConst = {
- install: spyRendererInstall
- };
- const bidRequests = [
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '50'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': 'e6e65553fc8',
- 'bidderRequestId': '1380f393215dc7',
- 'auctionId': '10b8d2f3c697e3',
- 'mediaTypes': {
- 'video': {
- 'context': 'outstream'
- }
- }
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '51'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': 'c8fdcb3f269f',
- 'bidderRequestId': '1380f393215dc7',
- 'auctionId': '10b8d2f3c697e3'
- },
- {
- 'bidder': 'trustx',
- 'params': {
- 'uid': '52'
- },
- 'adUnitCode': 'adunit-code-1',
- 'sizes': [[300, 250], [300, 600]],
- 'bidId': '1de036c37685',
- 'bidderRequestId': '1380f393215dc7',
- 'auctionId': '10b8d2f3c697e3',
- 'renderer': {}
- }
- ];
- const response = [
- {'bid': [{'impid': 'e6e65553fc8', 'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 50, content_type: 'video', w: 300, h: 600}], 'seat': '2'},
- {'bid': [{'impid': 'c8fdcb3f269f', 'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 51, content_type: 'video', w: 300, h: 250}], 'seat': '2'},
- {'bid': [{'impid': '1de036c37685', 'price': 1.20, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 52, content_type: 'video', w: 300, h: 250}], 'seat': '2'}
- ];
- const request = spec.buildRequests(bidRequests);
- const expectedResponse = [
- {
- 'requestId': 'e6e65553fc8',
- 'cpm': 1.15,
- 'creativeId': 50,
- 'dealId': undefined,
- 'width': 300,
- 'height': 600,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- 'vastXml': '\n<\/Ad>\n<\/VAST>',
- 'adResponse': {
- 'content': '\n<\/Ad>\n<\/VAST>'
- },
- 'renderer': stubRenderer
- },
- {
- 'requestId': 'c8fdcb3f269f',
- 'cpm': 1.00,
- 'creativeId': 51,
- 'dealId': undefined,
- 'width': 300,
- 'height': 250,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- 'vastXml': '\n<\/Ad>\n<\/VAST>',
- 'adResponse': {
- 'content': '\n<\/Ad>\n<\/VAST>'
- },
- 'renderer': stubRenderer
- },
- {
- 'requestId': '1de036c37685',
- 'cpm': 1.20,
- 'creativeId': 52,
- 'dealId': undefined,
- 'width': 300,
- 'height': 250,
- 'currency': 'USD',
- 'mediaType': 'video',
- 'netRevenue': false,
- 'ttl': 360,
- 'meta': {
- 'advertiserDomains': []
- },
- 'vastXml': '\n<\/Ad>\n<\/VAST>',
- 'adResponse': {
- 'content': '\n<\/Ad>\n<\/VAST>'
- }
- }
- ];
-
- const result = spec.interpretResponse({'body': {'seatbid': response}}, request, stubRendererConst);
-
- expect(spySetRenderer.calledTwice).to.equal(true);
- expect(spySetRenderer.getCall(0).args[0]).to.be.a('function');
- expect(spySetRenderer.getCall(1).args[0]).to.be.a('function');
-
- expect(spyRendererInstall.calledTwice).to.equal(true);
- expect(spyRendererInstall.getCall(0).args[0]).to.deep.equal({
- id: 'e6e65553fc8',
- url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
- loaded: false
- });
- expect(spyRendererInstall.getCall(1).args[0]).to.deep.equal({
- id: 'c8fdcb3f269f',
- url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
- loaded: false
- });
-
- expect(result).to.deep.equal(expectedResponse);
- });
-});
diff --git a/test/spec/modules/ttdBidAdapter_spec.js b/test/spec/modules/ttdBidAdapter_spec.js
index 099e5e56c33..aa2e84b619e 100644
--- a/test/spec/modules/ttdBidAdapter_spec.js
+++ b/test/spec/modules/ttdBidAdapter_spec.js
@@ -17,8 +17,7 @@ describe('ttdBidAdapter', function () {
'params': {
'supplySourceId': 'supplier',
'publisherId': '22222222',
- 'placementId': 'some-PlacementId_1',
- 'siteId': 'testSiteId'
+ 'placementId': 'some-PlacementId_1'
},
'mediaTypes': {
'banner': {
@@ -57,27 +56,20 @@ describe('ttdBidAdapter', function () {
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
- it('should return false when siteId not passed', function () {
- let bid = makeBid();
- delete bid.params.siteId;
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
-
- it('should return false when siteId is longer than 50 characters', function () {
- let bid = makeBid();
- bid.params.siteId = '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'
- expect(spec.isBidRequestValid(bid)).to.equal(false);
- });
-
- it('should return false when placementId not passed', function () {
+ it('should return true if placementId is not passed and gpid is passed', function () {
let bid = makeBid();
delete bid.params.placementId;
- expect(spec.isBidRequestValid(bid)).to.equal(false);
+ bid.ortb2Imp = {
+ ext: {
+ gpid: '/1111/home#header'
+ }
+ }
+ expect(spec.isBidRequestValid(bid)).to.equal(true);
});
- it('should return false when the placementId is longer than 128 characters', function () {
+ it('should return false if neither placementId nor gpid is passed', function () {
let bid = makeBid();
- bid.params.placementId = '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'; // 130 characters
+ delete bid.params.placementId;
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
@@ -103,7 +95,6 @@ describe('ttdBidAdapter', function () {
'params': {
'supplySourceId': 'supplier',
'publisherId': '22222222',
- 'siteId': 'testSiteId123',
'placementId': 'somePlacementId'
},
'mediaTypes': {
@@ -187,17 +178,21 @@ describe('ttdBidAdapter', function () {
'params': {
'supplySourceId': 'supplier',
'publisherId': '13144370',
- 'placementId': '1gaa015',
- 'siteId': 'testSiteId123'
+ 'placementId': '1gaa015'
},
'mediaTypes': {
'banner': {
'sizes': [[300, 250], [300, 600]]
}
},
+ 'ortb2Imp': {
+ 'ext': {
+ 'tid': '8651474f-58b1-4368-b812-84f8c937a099',
+ }
+ },
'sizes': [[300, 250], [300, 600]],
+ 'transactionId': '1111474f-58b1-4368-b812-84f8c937a099',
'adUnitCode': 'div-gpt-ad-1460505748561-0',
- 'transactionId': '8651474f-58b1-4368-b812-84f8c937a099',
'bidId': '243310435309b5',
'bidderRequestId': '18084284054531',
'auctionId': 'e7b34fa3-8654-424e-8c49-03e509e53d8c',
@@ -212,7 +207,7 @@ describe('ttdBidAdapter', function () {
'auctionStart': 1540945362095,
'timeout': 3000,
'refererInfo': {
- 'referer': 'https://www.example.com/test',
+ 'page': 'https://www.example.com/test',
'reachedTop': true,
'numIframes': 0,
'stack': [
@@ -240,16 +235,49 @@ describe('ttdBidAdapter', function () {
expect(url).to.equal('https://direct.adsrvr.org/bid/bidder/supplier');
});
- it('sends publisher id, site id, and placement id', function () {
+ it('sends publisher id', function () {
const requestBody = testBuildRequests(baseBannerBidRequests, baseBidderRequest).data;
expect(requestBody.site).to.be.not.null;
expect(requestBody.site.publisher).to.be.not.null;
- expect(requestBody.imp[0].tagid).to.be.not.null;
expect(requestBody.site.publisher.id).to.equal(baseBannerBidRequests[0].params.publisherId);
- expect(requestBody.site.id).to.equal(baseBannerBidRequests[0].params.siteId);
+ });
+
+ it('sends placement id in tagid', function () {
+ const requestBody = testBuildRequests(baseBannerBidRequests, baseBidderRequest).data;
expect(requestBody.imp[0].tagid).to.equal(baseBannerBidRequests[0].params.placementId);
});
+ it('sends gpid in tagid if present', function () {
+ let clonedBannerRequests = deepClone(baseBannerBidRequests);
+ const gpid = '/1111/home#header';
+ clonedBannerRequests[0].ortb2Imp = {
+ ext: {
+ gpid: gpid
+ }
+ };
+ const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
+ expect(requestBody.imp[0].tagid).to.equal(gpid);
+ });
+
+ it('sends gpid in ext.gpid if present', function () {
+ let clonedBannerRequests = deepClone(baseBannerBidRequests);
+ const gpid = '/1111/home#header';
+ clonedBannerRequests[0].ortb2Imp = {
+ ext: {
+ gpid: gpid
+ }
+ };
+ const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
+ expect(requestBody.imp[0].ext).to.be.not.null;
+ expect(requestBody.imp[0].ext.gpid).to.equal(gpid);
+ });
+
+ it('sends transaction id in source.tid', function () {
+ const requestBody = testBuildRequests(baseBannerBidRequests, baseBidderRequest).data;
+ expect(requestBody.source).to.be.not.null;
+ expect(requestBody.source.tid).to.equal('1111474f-58b1-4368-b812-84f8c937a099');
+ });
+
it('includes the ad size in the bid request', function () {
const requestBody = testBuildRequests(baseBannerBidRequests, baseBidderRequest).data;
expect(requestBody.imp[0].banner.format[0].w).to.equal(300);
@@ -283,18 +311,44 @@ describe('ttdBidAdapter', function () {
});
it('sets keywords properly if sent', function () {
- let clonedBannerRequests = deepClone(baseBannerBidRequests);
-
- config.setConfig({ortb2: {
+ const ortb2 = {
site: {
keywords: 'highViewability, clothing, holiday shopping'
}
- }});
- const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
+ };
+ const requestBody = testBuildRequests(baseBannerBidRequests, {...baseBidderRequest, ortb2}).data;
config.resetConfig();
expect(requestBody.ext.ttdprebid.keywords).to.deep.equal(['highViewability', 'clothing', 'holiday shopping']);
});
+ it('sets bcat properly if sent', function () {
+ const ortb2 = {
+ bcat: ['IAB1-1', 'IAB2-9']
+ };
+ const requestBody = testBuildRequests(baseBannerBidRequests, {...baseBidderRequest, ortb2}).data;
+ config.resetConfig();
+ expect(requestBody.bcat).to.deep.equal(['IAB1-1', 'IAB2-9']);
+ });
+
+ it('sets badv properly if sent', function () {
+ const ortb2 = {
+ badv: ['adv1.com', 'adv2.com']
+ };
+ const requestBody = testBuildRequests(baseBannerBidRequests, {...baseBidderRequest, ortb2}).data;
+ config.resetConfig();
+ expect(requestBody.badv).to.deep.equal(['adv1.com', 'adv2.com']);
+ });
+
+ it('sets battr properly if present', function () {
+ let clonedBannerRequests = deepClone(baseBannerBidRequests);
+ const battr = [1, 2, 3];
+ clonedBannerRequests[0].ortb2Imp = {
+ battr: battr
+ };
+ const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
+ expect(requestBody.imp[0].banner.battr).to.equal(battr);
+ });
+
it('sets ext properly', function () {
let clonedBannerRequests = deepClone(baseBannerBidRequests);
@@ -404,9 +458,7 @@ describe('ttdBidAdapter', function () {
});
it('adds first party site data to the request', function () {
- let clonedBidderRequest = deepClone(baseBidderRequest);
-
- config.setConfig({ortb2: {
+ const ortb2 = {
site: {
name: 'example',
domain: 'page.example.com',
@@ -417,9 +469,9 @@ describe('ttdBidAdapter', function () {
ref: 'https://ref.example.com',
keywords: 'power tools, drills'
}
- }});
+ };
+ let clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2};
const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data;
- config.resetConfig();
expect(requestBody.site.name).to.equal('example');
expect(requestBody.site.domain).to.equal('page.example.com');
expect(requestBody.site.cat[0]).to.equal('IAB2');
@@ -444,9 +496,14 @@ describe('ttdBidAdapter', function () {
'sizes': [[300, 250], [300, 600]]
}
},
+ 'ortb2Imp': {
+ 'ext': {
+ 'tid': '8651474f-58b1-4368-b812-84f8c937a099',
+ }
+ },
'sizes': [[300, 250], [300, 600]],
+ 'transactionId': '1111474f-58b1-4368-b812-84f8c937a099',
'adUnitCode': 'div-gpt-ad-1460505748561-0',
- 'transactionId': '8651474f-58b1-4368-b812-84f8c937a099',
'bidId': 'small',
'bidderRequestId': '18084284054531',
'auctionId': 'e7b34fa3-8654-424e-8c49-03e509e53d8c',
@@ -456,17 +513,21 @@ describe('ttdBidAdapter', function () {
'bidder': 'ttd',
'params': {
'publisherId': '13144370',
- 'placementId': 'top',
- 'siteId': 'testSite123'
+ 'placementId': 'top'
},
'mediaTypes': {
'banner': {
'sizes': [[728, 90]]
}
},
+ 'ortb2Imp': {
+ 'ext': {
+ 'tid': '12345678-58b1-4368-b812-84f8c937a099',
+ }
+ },
'sizes': [[728, 90]],
- 'adUnitCode': 'div-gpt-ad-91515710-0',
'transactionId': '825c1228-ca8c-4657-b40f-2df500621527',
+ 'adUnitCode': 'div-gpt-ad-91515710-0',
'bidId': 'large',
'bidderRequestId': '18084284054531',
'auctionId': 'e7b34fa3-8654-424e-8c49-03e509e53d8c',
@@ -495,6 +556,12 @@ describe('ttdBidAdapter', function () {
it('sends multiple impressions', function () {
const requestBody = testBuildRequests(baseBannerMultipleBidRequests, baseBidderRequest).data;
expect(requestBody.imp.length).to.equal(2);
+ expect(requestBody.source).to.be.not.null;
+ expect(requestBody.source.tid).to.equal('1111474f-58b1-4368-b812-84f8c937a099');
+ expect(requestBody.imp[0].ext).to.be.not.null;
+ expect(requestBody.imp[0].ext.tid).to.equal('8651474f-58b1-4368-b812-84f8c937a099');
+ expect(requestBody.imp[1].ext).to.be.not.null;
+ expect(requestBody.imp[1].ext.tid).to.equal('12345678-58b1-4368-b812-84f8c937a099');
});
it('sends the right tag ids for each ad unit', function () {
@@ -549,8 +616,13 @@ describe('ttdBidAdapter', function () {
'sizes': [[300, 250], [300, 600]]
}
},
+ 'ortb2Imp': {
+ 'ext': {
+ 'tid': '8651474f-58b1-4368-b812-84f8c937a099',
+ }
+ },
+ 'transactionId': '1111474f-58b1-4368-b812-84f8c937a099',
'adUnitCode': 'div-gpt-ad-1460505748561-0',
- 'transactionId': '8651474f-58b1-4368-b812-84f8c937a099',
'bidId': '243310435309b5',
'bidderRequestId': '18084284054531',
'auctionId': 'e7b34fa3-8654-424e-8c49-03e509e53d8c',
@@ -609,8 +681,13 @@ describe('ttdBidAdapter', function () {
'maxduration': 30
}
},
+ 'ortb2Imp': {
+ 'ext': {
+ 'tid': '8651474f-58b1-4368-b812-84f8c937a099',
+ }
+ },
+ 'transactionId': '1111474f-58b1-4368-b812-84f8c937a099',
'adUnitCode': 'div-gpt-ad-1460505748561-0',
- 'transactionId': '8651474f-58b1-4368-b812-84f8c937a099',
'bidId': '243310435309b5',
'bidderRequestId': '18084284054531',
'auctionId': 'e7b34fa3-8654-424e-8c49-03e509e53d8c',
diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js
index ac788e537e2..76e448b7694 100644
--- a/test/spec/modules/ucfunnelBidAdapter_spec.js
+++ b/test/spec/modules/ucfunnelBidAdapter_spec.js
@@ -17,7 +17,6 @@ const userId = {
'tdid': 'D6885E90-2A7A-4E0F-87CB-7734ED1B99A3',
'haloId': {},
'uid2': {'id': 'eb33b0cb-8d35-4722-b9c0-1a31d4064888'},
- 'flocId': {'id': '12144', 'version': 'chrome.1.1'},
'connectid': '4567'
}
@@ -160,7 +159,6 @@ describe('ucfunnel Adapter', function () {
expect(data.w).to.equal(width);
expect(data.h).to.equal(height);
expect(data.eids).to.equal('uid2,eb33b0cb-8d35-4722-b9c0-1a31d4064888!verizonMediaId,4567');
- expect(data.cid).to.equal('12144');
expect(data.schain).to.equal('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com');
});
diff --git a/test/spec/modules/undertoneBidAdapter_spec.js b/test/spec/modules/undertoneBidAdapter_spec.js
index c24f63c0b99..8766307b3bd 100644
--- a/test/spec/modules/undertoneBidAdapter_spec.js
+++ b/test/spec/modules/undertoneBidAdapter_spec.js
@@ -152,13 +152,13 @@ const bidReqUserIds = [{
const bidderReq = {
refererInfo: {
- referer: 'http://prebid.org/dev-docs/bidder-adaptor.html'
+ topmostLocation: 'http://prebid.org/dev-docs/bidder-adaptor.html'
}
};
const bidderReqGdpr = {
refererInfo: {
- referer: 'http://prebid.org/dev-docs/bidder-adaptor.html'
+ topmostLocation: 'http://prebid.org/dev-docs/bidder-adaptor.html'
},
gdprConsent: {
gdprApplies: true,
@@ -168,14 +168,14 @@ const bidderReqGdpr = {
const bidderReqCcpa = {
refererInfo: {
- referer: 'http://prebid.org/dev-docs/bidder-adaptor.html'
+ topmostLocation: 'http://prebid.org/dev-docs/bidder-adaptor.html'
},
uspConsent: 'NY12'
};
const bidderReqCcpaAndGdpr = {
refererInfo: {
- referer: 'http://prebid.org/dev-docs/bidder-adaptor.html'
+ topmostLocation: 'http://prebid.org/dev-docs/bidder-adaptor.html'
},
gdprConsent: {
gdprApplies: true,
@@ -343,18 +343,18 @@ describe('Undertone Adapter', () => {
});
it('should send request to correct url via POST not in GDPR or CCPA', function () {
const request = spec.buildRequests(bidReq, bidderReq);
- const domainStart = bidderReq.refererInfo.referer.indexOf('//');
- const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2);
- const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd);
+ const domainStart = bidderReq.refererInfo.topmostLocation.indexOf('//');
+ const domainEnd = bidderReq.refererInfo.topmostLocation.indexOf('/', domainStart + 2);
+ const domain = bidderReq.refererInfo.topmostLocation.substring(domainStart + 2, domainEnd);
const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}`;
expect(request.url).to.equal(REQ_URL);
expect(request.method).to.equal('POST');
});
it('should send request to correct url via POST when in GDPR', function () {
const request = spec.buildRequests(bidReq, bidderReqGdpr);
- const domainStart = bidderReq.refererInfo.referer.indexOf('//');
- const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2);
- const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd);
+ const domainStart = bidderReq.refererInfo.topmostLocation.indexOf('//');
+ const domainEnd = bidderReq.refererInfo.topmostLocation.indexOf('/', domainStart + 2);
+ const domain = bidderReq.refererInfo.topmostLocation.substring(domainStart + 2, domainEnd);
let gdpr = bidderReqGdpr.gdprConsent.gdprApplies ? 1 : 0;
const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&gdpr=${gdpr}&gdprstr=${bidderReqGdpr.gdprConsent.consentString}`;
expect(request.url).to.equal(REQ_URL);
@@ -362,9 +362,9 @@ describe('Undertone Adapter', () => {
});
it('should send request to correct url via POST when in CCPA', function () {
const request = spec.buildRequests(bidReq, bidderReqCcpa);
- const domainStart = bidderReq.refererInfo.referer.indexOf('//');
- const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2);
- const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd);
+ const domainStart = bidderReq.refererInfo.topmostLocation.indexOf('//');
+ const domainEnd = bidderReq.refererInfo.topmostLocation.indexOf('/', domainStart + 2);
+ const domain = bidderReq.refererInfo.topmostLocation.substring(domainStart + 2, domainEnd);
let ccpa = bidderReqCcpa.uspConsent;
const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&ccpa=${ccpa}`;
expect(request.url).to.equal(REQ_URL);
@@ -372,9 +372,9 @@ describe('Undertone Adapter', () => {
});
it('should send request to correct url via POST when in GDPR and CCPA', function () {
const request = spec.buildRequests(bidReq, bidderReqCcpaAndGdpr);
- const domainStart = bidderReq.refererInfo.referer.indexOf('//');
- const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2);
- const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd);
+ const domainStart = bidderReq.refererInfo.topmostLocation.indexOf('//');
+ const domainEnd = bidderReq.refererInfo.topmostLocation.indexOf('/', domainStart + 2);
+ const domain = bidderReq.refererInfo.topmostLocation.substring(domainStart + 2, domainEnd);
let ccpa = bidderReqCcpaAndGdpr.uspConsent;
let gdpr = bidderReqCcpaAndGdpr.gdprConsent.gdprApplies ? 1 : 0;
const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&gdpr=${gdpr}&gdprstr=${bidderReqGdpr.gdprConsent.consentString}&ccpa=${ccpa}`;
diff --git a/test/spec/modules/unicornBidAdapter_spec.js b/test/spec/modules/unicornBidAdapter_spec.js
index 1ab428d58b6..0abb09bfb78 100644
--- a/test/spec/modules/unicornBidAdapter_spec.js
+++ b/test/spec/modules/unicornBidAdapter_spec.js
@@ -270,7 +270,7 @@ const bidderRequest = {
auctionStart: 1581064124172,
timeout: 1000,
refererInfo: {
- referer: 'https://uni-corn.net/',
+ ref: 'https://uni-corn.net/',
reachedTop: true,
numIframes: 0,
stack: ['https://uni-corn.net/']
@@ -496,6 +496,16 @@ describe('unicornBidAdapterTest', () => {
});
describe('buildBidRequest', () => {
+ before(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ unicorn: {
+ storageAllowed: true
+ }
+ };
+ });
+ after(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
+ });
it('buildBidRequest', () => {
const req = spec.buildRequests(validBidRequests, bidderRequest);
const removeUntestableAttrs = data => {
diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js
index a90056a7538..e6058673d41 100644
--- a/test/spec/modules/userId_spec.js
+++ b/test/spec/modules/userId_spec.js
@@ -30,7 +30,6 @@ import {dmdIdSubmodule} from 'modules/dmdIdSystem.js';
import {liveIntentIdSubmodule} from 'modules/liveIntentIdSystem.js';
import {merkleIdSubmodule} from 'modules/merkleIdSystem.js';
import {netIdSubmodule} from 'modules/netIdSystem.js';
-import {nextrollIdSubmodule} from 'modules/nextrollIdSystem.js';
import {intentIqIdSubmodule} from 'modules/intentIqIdSystem.js';
import {zeotapIdPlusSubmodule} from 'modules/zeotapIdPlusIdSystem.js';
import {sharedIdSystemSubmodule} from 'modules/sharedIdSystem.js';
@@ -39,20 +38,21 @@ import {pubProvidedIdSubmodule} from 'modules/pubProvidedIdSystem.js';
import {criteoIdSubmodule} from 'modules/criteoIdSystem.js';
import {mwOpenLinkIdSubModule} from 'modules/mwOpenLinkIdSystem.js';
import {tapadIdSubmodule} from 'modules/tapadIdSystem.js';
+import {tncidSubModule} from 'modules/tncIdSystem.js';
import {getPrebidInternal} from 'src/utils.js';
import {uid2IdSubmodule} from 'modules/uid2IdSystem.js';
import {admixerIdSubmodule} from 'modules/admixerIdSystem.js';
import {deepintentDpesSubmodule} from 'modules/deepintentDpesIdSystem.js';
-import {flocIdSubmodule} from 'modules/flocIdSystem.js'
import {amxIdSubmodule} from '../../../modules/amxIdSystem.js';
-import {akamaiDAPIdSubmodule} from 'modules/akamaiDAPIdSystem.js'
-import {kinessoIdSubmodule} from 'modules/kinessoIdSystem.js'
+import {kinessoIdSubmodule} from 'modules/kinessoIdSystem.js';
import {adqueryIdSubmodule} from 'modules/adqueryIdSystem.js';
+import {imuIdSubmodule} from 'modules/imuIdSystem.js';
import * as mockGpt from '../integration/faker/googletag.js';
import 'src/prebid.js';
import {hook} from '../../../src/hook.js';
import {mockGdprConsent} from '../../helpers/consentData.js';
import {getPPID} from '../../../src/adserver.js';
+import {uninstall as uninstallGdprEnforcement} from 'modules/gdprEnforcement.js';
let assert = require('chai').assert;
let expect = require('chai').expect;
@@ -145,6 +145,7 @@ describe('User ID', function () {
before(function () {
hook.ready();
+ uninstallGdprEnforcement();
localStorage.removeItem(PBJS_USER_ID_OPTOUT_NAME);
});
@@ -402,7 +403,7 @@ describe('User ID', function () {
it('should set googletag ppid correctly', function () {
let adUnits = [getAdUnitMock()];
init(config);
- setSubmoduleRegistry([amxIdSubmodule, sharedIdSystemSubmodule, identityLinkSubmodule]);
+ setSubmoduleRegistry([amxIdSubmodule, sharedIdSystemSubmodule, identityLinkSubmodule, imuIdSubmodule]);
config.setConfig({
userSync: {
@@ -411,6 +412,7 @@ describe('User ID', function () {
{ name: 'amxId', value: {'amxId': 'amx-id-value-amx-id-value-amx-id-value'} },
{ name: 'pubCommonId', value: {'pubcid': 'pubCommon-id-value-pubCommon-id-value'} },
{ name: 'identityLink', value: {'idl_env': 'identityLink-id-value-identityLink-id-value'} },
+ { name: 'imuid', value: {'imppid': 'imppid-value-imppid-value-imppid-value'} },
]
}
});
@@ -422,6 +424,27 @@ describe('User ID', function () {
});
});
+ it('should set googletag ppid correctly for imuIdSubmodule', function () {
+ let adUnits = [getAdUnitMock()];
+ init(config);
+ setSubmoduleRegistry([imuIdSubmodule]);
+
+ config.setConfig({
+ userSync: {
+ ppid: 'ppid.intimatemerger.com',
+ userIds: [
+ { name: 'imuid', value: {'imppid': 'imppid-value-imppid-value-imppid-value'} },
+ ]
+ }
+ });
+ // before ppid should not be set
+ expect(window.googletag._ppid).to.equal(undefined);
+ return expectImmediateBidHook(() => {}, {adUnits}).then(() => {
+ // ppid should have been set without dashes and stuff
+ expect(window.googletag._ppid).to.equal('imppidvalueimppidvalueimppidvalue');
+ });
+ });
+
it('should log a warning if PPID too big or small', function () {
let adUnits = [getAdUnitMock()];
@@ -466,6 +489,7 @@ describe('User ID', function () {
describe('refreshing before init is complete', () => {
const MOCK_ID = {'MOCKID': '1111'};
let mockIdCallback;
+ let startInit;
beforeEach(() => {
mockIdCallback = sinon.stub();
@@ -480,7 +504,7 @@ describe('User ID', function () {
};
init(config);
setSubmoduleRegistry([mockIdSystem]);
- config.setConfig({
+ startInit = () => config.setConfig({
userSync: {
auctionDelay: 10,
userIds: [{
@@ -492,6 +516,7 @@ describe('User ID', function () {
});
it('should still resolve promises returned by getUserIdsAsync', () => {
+ startInit();
let result = null;
getGlobal().getUserIdsAsync().then((val) => { result = val; });
return clearStack().then(() => {
@@ -506,6 +531,7 @@ describe('User ID', function () {
it('should not stop auctions', (done) => {
// simulate an infinite `auctionDelay`; refreshing should still allow the auction to continue
// as soon as ID submodules have completed init
+ startInit();
requestBidsHook(() => {
done();
}, {adUnits: [getAdUnitMock()]}, {delay: delay()});
@@ -513,12 +539,26 @@ describe('User ID', function () {
clearStack().then(() => {
// simulate init complete
mockIdCallback.callArg(0, {id: {MOCKID: '1111'}});
- })
+ });
});
+ it('should continue the auction when init fails', (done) => {
+ startInit();
+ requestBidsHook(() => {
+ done();
+ },
+ {adUnits: [getAdUnitMock()]},
+ {
+ delay: delay(),
+ getIds: () => Promise.reject(new Error())
+ }
+ );
+ })
+
it('should not get stuck when init fails', () => {
const err = new Error();
mockIdCallback.callsFake(() => { throw err; });
+ startInit();
return getGlobal().getUserIdsAsync().catch((e) =>
expect(e).to.equal(err)
);
@@ -694,11 +734,15 @@ describe('User ID', function () {
config.resetConfig();
});
- it('fails initialization if opt out cookie exists', function () {
+ it('does not fetch ids if opt out cookie exists', function () {
init(config);
setSubmoduleRegistry([sharedIdSystemSubmodule]);
- config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie']));
- expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - opt-out cookie found, exit module');
+ const cfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']);
+ cfg.userSync.auctionDelay = 1; // to let init complete without an auction
+ config.setConfig(cfg);
+ return getGlobal().getUserIdsAsync().then((uid) => {
+ expect(uid).to.eql({});
+ })
});
it('initializes if no opt out cookie exists', function () {
@@ -722,7 +766,7 @@ describe('User ID', function () {
it('handles config with no usersync object', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({});
// usersync is undefined, and no logInfo message for 'User ID - usersync config updated'
expect(typeof utils.logInfo.args[0]).to.equal('undefined');
@@ -730,14 +774,14 @@ describe('User ID', function () {
it('handles config with empty usersync object', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({userSync: {}});
expect(typeof utils.logInfo.args[0]).to.equal('undefined');
});
it('handles config with usersync and userIds that are empty objs', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, nextrollIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({
userSync: {
userIds: [{}]
@@ -748,7 +792,7 @@ describe('User ID', function () {
it('handles config with usersync and userIds with empty names or that dont match a submodule.name', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, nextrollIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({
userSync: {
userIds: [{
@@ -765,7 +809,7 @@ describe('User ID', function () {
it('config with 1 configurations should create 1 submodules', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig(getConfigMock(['unifiedId', 'unifiedid', 'cookie']));
expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 1 submodules');
@@ -785,9 +829,9 @@ describe('User ID', function () {
expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 1 submodules');
});
- it('config with 24 configurations should result in 24 submodules add', function () {
+ it('config with 22 configurations should result in 22 submodules add', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, nextrollIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule, tncidSubModule]);
config.setConfig({
userSync: {
syncDelay: 0,
@@ -813,8 +857,6 @@ describe('User ID', function () {
}, {
name: 'netId',
storage: {name: 'netId', type: 'cookie'}
- }, {
- name: 'nextrollId'
}, {
name: 'intentIqId',
storage: {name: 'intentIqId', type: 'cookie'}
@@ -838,10 +880,6 @@ describe('User ID', function () {
}, {
name: 'deepintentId',
storage: {name: 'deepintentId', type: 'cookie'}
- }, {
- name: 'flocId'
- }, {
- name: 'akamaiDAPId'
}, {
name: 'dmdId',
storage: {name: 'dmdId', type: 'cookie'}
@@ -854,15 +892,17 @@ describe('User ID', function () {
}, {
name: 'qid',
storage: {name: 'qid', type: 'html5'}
+ }, {
+ name: 'tncId'
}]
}
});
- expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 24 submodules');
+ expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 22 submodules');
});
it('config syncDelay updates module correctly', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({
userSync: {
syncDelay: 99,
@@ -877,7 +917,7 @@ describe('User ID', function () {
it('config auctionDelay updates module correctly', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({
userSync: {
auctionDelay: 100,
@@ -892,7 +932,7 @@ describe('User ID', function () {
it('config auctionDelay defaults to 0 if not a number', function () {
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({
userSync: {
auctionDelay: '',
@@ -1821,7 +1861,7 @@ describe('User ID', function () {
}, {adUnits});
});
- it('test hook from merkleId cookies', function (done) {
+ it('test hook from merkleId cookies - legacy', function (done) {
// simulate existing browser local storage values
coreStorage.setCookie('merkleId', JSON.stringify({'pam_id': {'id': 'testmerkleId', 'keyID': 1}}), (new Date(Date.now() + 5000).toUTCString()));
@@ -1845,6 +1885,32 @@ describe('User ID', function () {
}, {adUnits});
});
+ it('test hook from merkleId cookies', function (done) {
+ // simulate existing browser local storage values
+ coreStorage.setCookie('merkleId', JSON.stringify({
+ 'merkleId': [{id: 'testmerkleId', ext: { keyID: 1, ssp: 'ssp1' }}, {id: 'another-random-id-value', ext: { ssp: 'ssp2' }}],
+ '_svsid': 'svs-id-1'
+ }), (new Date(Date.now() + 5000).toUTCString()));
+
+ init(config);
+ setSubmoduleRegistry([merkleIdSubmodule]);
+ config.setConfig(getConfigMock(['merkleId', 'merkleId', 'cookie']));
+
+ requestBidsHook(function () {
+ adUnits.forEach(unit => {
+ unit.bids.forEach(bid => {
+ expect(bid).to.have.deep.nested.property('userId.merkleId');
+ expect(bid.userId.merkleId.length).to.equal(2);
+ expect(bid.userIdAsEids.length).to.equal(2);
+ expect(bid.userIdAsEids[0]).to.deep.equal({ source: 'ssp1.merkleinc.com', uids: [{id: 'testmerkleId', atype: 3, ext: { keyID: 1, ssp: 'ssp1' }}] });
+ expect(bid.userIdAsEids[1]).to.deep.equal({ source: 'ssp2.merkleinc.com', uids: [{id: 'another-random-id-value', atype: 3, ext: { ssp: 'ssp2' }}] });
+ });
+ });
+ coreStorage.setCookie('merkleId', '', EXPIRED_COOKIE_DATE);
+ done();
+ }, {adUnits});
+ });
+
it('test hook from zeotapIdPlus cookies', function (done) {
// simulate existing browser local storage values
coreStorage.setCookie('IDP', btoa(JSON.stringify('abcdefghijk')), (new Date(Date.now() + 5000).toUTCString()));
@@ -2195,7 +2261,7 @@ describe('User ID', function () {
localStorage.setItem('qid_exp', new Date(Date.now() + 5000).toUTCString())
init(config);
- setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, akamaiDAPIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
+ setSubmoduleRegistry([sharedIdSystemSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, hadronIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, amxIdSubmodule, kinessoIdSubmodule, adqueryIdSubmodule]);
config.setConfig({
userSync: {
@@ -2509,7 +2575,6 @@ describe('User ID', function () {
// init id system
attachIdSystem(mockIdSystem);
- config.setConfig(userIdConfig);
});
afterEach(function () {
@@ -2520,6 +2585,8 @@ describe('User ID', function () {
coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr);
coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 1 * 1000).toUTCString()), expStr);
+ config.setConfig(userIdConfig);
+
let innerAdUnits;
return runBidsHook((config) => {
innerAdUnits = config.adUnits
@@ -2534,6 +2601,8 @@ describe('User ID', function () {
coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr);
coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 60 * 1000).toUTCString()), expStr);
+ config.setConfig(userIdConfig);
+
let innerAdUnits;
return runBidsHook((config) => {
innerAdUnits = config.adUnits
@@ -2550,6 +2619,8 @@ describe('User ID', function () {
setStoredConsentData();
+ config.setConfig(userIdConfig);
+
let innerAdUnits;
return runBidsHook((config) => {
innerAdUnits = config.adUnits
@@ -2566,6 +2637,8 @@ describe('User ID', function () {
setStoredConsentData({...consentData, consentString: 'different'});
+ config.setConfig(userIdConfig);
+
let innerAdUnits;
return runBidsHook((config) => {
innerAdUnits = config.adUnits
@@ -2582,6 +2655,8 @@ describe('User ID', function () {
setStoredConsentData({...consentData});
+ config.setConfig(userIdConfig);
+
let innerAdUnits;
return runBidsHook((config) => {
innerAdUnits = config.adUnits
diff --git a/test/spec/modules/ventesBidAdapter_spec.js b/test/spec/modules/ventesBidAdapter_spec.js
index 219c24deced..8e1a747f6f7 100644
--- a/test/spec/modules/ventesBidAdapter_spec.js
+++ b/test/spec/modules/ventesBidAdapter_spec.js
@@ -2,7 +2,7 @@ import { expect } from 'chai';
import * as utils from 'src/utils.js';
import { spec } from 'modules/ventesBidAdapter.js';
-const BIDDER_URL = 'http://13.234.201.146:8088/va/ad';
+const BIDDER_URL = 'https://ad.ventesavenues.in/va/ad';
describe('Ventes Adapter', function () {
const examples = {
@@ -28,13 +28,14 @@ describe('Ventes Adapter', function () {
adUnitContext: {
refererInfo: {
- referer: 'https://ventesavenues.in',
+ page: 'https://ventesavenues.in',
+ domain: 'ventesavenues.in',
}
},
serverRequest_banner: {
method: 'POST',
- url: 'http://13.234.201.146:8088/va/ad',
+ url: BIDDER_URL,
data: {
id: 'bid_request_id',
imp: [
@@ -373,7 +374,7 @@ describe('Ventes Adapter', function () {
expect(serverRequests[0].data).to.exist.and.to.be.an('object');
expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId);
expect(serverRequests[0].data.site).to.exist.and.to.be.an('object');
- expect(serverRequests[0].data.site.page).to.exist.and.to.be.an('string').and.to.equal(adUnitContext.refererInfo.referer);
+ expect(serverRequests[0].data.site.page).to.exist.and.to.be.an('string').and.to.equal(adUnitContext.refererInfo.page);
expect(serverRequests[0].data.site.domain).to.exist.and.to.be.an('string').and.to.equal('ventesavenues.in');
expect(serverRequests[0].data.site.name).to.exist.and.to.be.an('string').and.to.equal('ventesavenues.in');
});
diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js
index 0b5dadce09f..d30b9f31417 100644
--- a/test/spec/modules/vidazooBidAdapter_spec.js
+++ b/test/spec/modules/vidazooBidAdapter_spec.js
@@ -1,4 +1,4 @@
-import { expect } from 'chai';
+import {expect} from 'chai';
import {
spec as adapter,
SUPPORTED_ID_SYSTEMS,
@@ -15,8 +15,8 @@ import {
getVidazooSessionId,
} from 'modules/vidazooBidAdapter.js';
import * as utils from 'src/utils.js';
-import { version } from 'package.json';
-import { useFakeTimers } from 'sinon';
+import {version} from 'package.json';
+import {useFakeTimers} from 'sinon';
const SUB_DOMAIN = 'openrtb';
@@ -48,12 +48,14 @@ const BIDDER_REQUEST = {
},
'uspConsent': 'consent_string',
'refererInfo': {
- 'referer': 'https://www.greatsite.com'
+ 'page': 'https://www.greatsite.com',
+ 'ref': 'https://www.somereferrer.com'
}
};
const SERVER_RESPONSE = {
body: {
+ cid: 'testcid123',
results: [{
'ad': '',
'price': 0.8,
@@ -81,6 +83,15 @@ const REQUEST = {
}
};
+function getTopWindowQueryParams() {
+ try {
+ const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true});
+ return parsedUrl.search;
+ } catch (e) {
+ return '';
+ }
+}
+
describe('VidazooBidAdapter', function () {
describe('validtae spec', function () {
it('exists and is a function', function () {
@@ -137,12 +148,17 @@ describe('VidazooBidAdapter', function () {
describe('build requests', function () {
let sandbox;
before(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ vidazoo: {
+ storageAllowed: true
+ }
+ };
sandbox = sinon.sandbox.create();
sandbox.stub(Date, 'now').returns(1000);
});
it('should build request for each size', function () {
- const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.referer);
+ const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page);
const requests = adapter.buildRequests([BID], BIDDER_REQUEST);
expect(requests).to.have.length(1);
expect(requests[0]).to.deep.equal({
@@ -154,6 +170,7 @@ describe('VidazooBidAdapter', function () {
usPrivacy: 'consent_string',
sizes: ['300x250', '300x600'],
url: 'https%3A%2F%2Fwww.greatsite.com',
+ referrer: 'https://www.somereferrer.com',
cb: 1000,
bidFloor: 0.1,
bidId: '2d52001cabd527',
@@ -166,6 +183,7 @@ describe('VidazooBidAdapter', function () {
prebidVersion: version,
schain: BID.schain,
res: `${window.top.screen.width}x${window.top.screen.height}`,
+ uqs: getTopWindowQueryParams(),
'ext.param1': 'loremipsum',
'ext.param2': 'dolorsitamet',
}
@@ -173,24 +191,33 @@ describe('VidazooBidAdapter', function () {
});
after(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
sandbox.restore();
});
});
describe('getUserSyncs', function () {
it('should have valid user sync with iframeEnabled', function () {
- const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]);
+ const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]);
+
+ expect(result).to.deep.equal([{
+ type: 'iframe',
+ url: 'https://sync.cootlogix.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy='
+ }]);
+ });
+ it('should have valid user sync with cid on response', function () {
+ const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]);
expect(result).to.deep.equal([{
type: 'iframe',
- url: 'https://prebid.cootlogix.com/api/sync/iframe/?gdpr=0&gdpr_consent=&us_privacy='
+ url: 'https://sync.cootlogix.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy='
}]);
});
it('should have valid user sync with pixelEnabled', function () {
- const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]);
+ const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]);
expect(result).to.deep.equal([{
- 'url': 'https://prebid.cootlogix.com/api/sync/image/?gdpr=0&gdpr_consent=&us_privacy=',
+ 'url': 'https://sync.cootlogix.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=',
'type': 'image'
}]);
})
@@ -203,12 +230,12 @@ describe('VidazooBidAdapter', function () {
});
it('should return empty array when there is no ad', function () {
- const responses = adapter.interpretResponse({ price: 1, ad: '' });
+ const responses = adapter.interpretResponse({price: 1, ad: ''});
expect(responses).to.be.empty;
});
it('should return empty array when there is no price', function () {
- const responses = adapter.interpretResponse({ price: null, ad: 'great ad' });
+ const responses = adapter.interpretResponse({price: null, ad: 'great ad'});
expect(responses).to.be.empty;
});
@@ -247,11 +274,14 @@ describe('VidazooBidAdapter', function () {
const userId = (function () {
switch (idSystemProvider) {
- case 'digitrustid': return { data: { id: id } };
- case 'lipb': return { lipbid: id };
- case 'parrableId': return { eid: id };
- case 'id5id': return { uid: id };
- default: return id;
+ case 'lipb':
+ return {lipbid: id};
+ case 'parrableId':
+ return {eid: id};
+ case 'id5id':
+ return {uid: id};
+ default:
+ return id;
}
})();
@@ -268,18 +298,18 @@ describe('VidazooBidAdapter', function () {
describe('alternate param names extractors', function () {
it('should return undefined when param not supported', function () {
- const cid = extractCID({ 'c_id': '1' });
- const pid = extractPID({ 'p_id': '1' });
- const subDomain = extractSubDomain({ 'sub_domain': 'prebid' });
+ const cid = extractCID({'c_id': '1'});
+ const pid = extractPID({'p_id': '1'});
+ const subDomain = extractSubDomain({'sub_domain': 'prebid'});
expect(cid).to.be.undefined;
expect(pid).to.be.undefined;
expect(subDomain).to.be.undefined;
});
it('should return value when param supported', function () {
- const cid = extractCID({ 'cID': '1' });
- const pid = extractPID({ 'Pid': '2' });
- const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' });
+ const cid = extractCID({'cID': '1'});
+ const pid = extractPID({'Pid': '2'});
+ const subDomain = extractSubDomain({'subDOMAIN': 'prebid'});
expect(cid).to.be.equal('1');
expect(pid).to.be.equal('2');
expect(subDomain).to.be.equal('prebid');
@@ -287,6 +317,16 @@ describe('VidazooBidAdapter', function () {
});
describe('vidazoo session id', function () {
+ before(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ vidazoo: {
+ storageAllowed: true
+ }
+ };
+ });
+ after(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
+ });
it('should get undefined vidazoo session id', function () {
const sessionId = getVidazooSessionId();
expect(sessionId).to.be.empty;
@@ -301,6 +341,16 @@ describe('VidazooBidAdapter', function () {
});
describe('deal id', function () {
+ before(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ vidazoo: {
+ storageAllowed: true
+ }
+ };
+ });
+ after(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
+ });
const key = 'myDealKey';
it('should get the next deal id', function () {
@@ -320,9 +370,21 @@ describe('VidazooBidAdapter', function () {
});
describe('unique deal id', function () {
+ before(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ vidazoo: {
+ storageAllowed: true
+ }
+ };
+ });
+ after(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
+ });
const key = 'myKey';
let uniqueDealId;
- uniqueDealId = getUniqueDealId(key);
+ beforeEach(() => {
+ uniqueDealId = getUniqueDealId(key, 0);
+ })
it('should get current unique deal id', function (done) {
// waiting some time so `now` will become past
@@ -333,13 +395,26 @@ describe('VidazooBidAdapter', function () {
}, 200);
});
- it('should get new unique deal id on expiration', function () {
- const current = getUniqueDealId(key, 100);
- expect(current).to.not.be.equal(uniqueDealId);
+ it('should get new unique deal id on expiration', function (done) {
+ setTimeout(() => {
+ const current = getUniqueDealId(key, 100);
+ expect(current).to.not.be.equal(uniqueDealId);
+ done();
+ }, 200)
});
});
describe('storage utils', function () {
+ before(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {
+ vidazoo: {
+ storageAllowed: true
+ }
+ };
+ });
+ after(function () {
+ $$PREBID_GLOBAL$$.bidderSettings = {};
+ });
it('should get value from storage with create param', function () {
const now = Date.now();
const clock = useFakeTimers({
@@ -347,7 +422,7 @@ describe('VidazooBidAdapter', function () {
now
});
setStorageItem('myKey', 2020);
- const { value, created } = getStorageItem('myKey');
+ const {value, created} = getStorageItem('myKey');
expect(created).to.be.equal(now);
expect(value).to.be.equal(2020);
expect(typeof value).to.be.equal('number');
@@ -363,8 +438,8 @@ describe('VidazooBidAdapter', function () {
});
it('should parse JSON value', function () {
- const data = JSON.stringify({ event: 'send' });
- const { event } = tryParseJSON(data);
+ const data = JSON.stringify({event: 'send'});
+ const {event} = tryParseJSON(data);
expect(event).to.be.equal('send');
});
diff --git a/test/spec/modules/videonowBidAdapter_spec.js b/test/spec/modules/videonowBidAdapter_spec.js
new file mode 100644
index 00000000000..c9eb5ba0bbf
--- /dev/null
+++ b/test/spec/modules/videonowBidAdapter_spec.js
@@ -0,0 +1,80 @@
+import {expect} from 'chai';
+import {spec} from 'modules/videonowBidAdapter';
+
+describe('videonowBidAdapter', function () {
+ it('minimal params', function () {
+ expect(spec.isBidRequestValid({
+ bidder: 'videonow',
+ params: {
+ pId: 'advDesktopBillboard'
+ }})).to.equal(true)
+ })
+
+ it('minimal params no placementId', function () {
+ expect(spec.isBidRequestValid({
+ bidder: 'videonow',
+ params: {
+ currency: `GBP`
+ }})).to.equal(false)
+ })
+
+ it('generated_params common case', function () {
+ const bidRequestData = [{
+ bidId: 'bid1234',
+ bidder: 'videonow',
+ params: {
+ pId: 'advDesktopBillboard',
+ currency: `GBP`
+ },
+ sizes: [[240, 400]]
+ }];
+
+ const request = spec.buildRequests(bidRequestData);
+ const req_data = request[0].data;
+
+ expect(req_data.places[0].id).to.equal(`bid1234`)
+ expect(req_data.places[0].placementId).to.equal(`advDesktopBillboard`)
+ expect(req_data.settings.currency).to.equal(`GBP`)
+ expect(req_data.places[0].sizes[0][0]).to.equal(240);
+ expect(req_data.places[0].sizes[0][1]).to.equal(400);
+ });
+
+ it('response_params common case', function () {
+ const bidRequestData = {
+ data: {
+ bidId: 'bid1234'
+ }
+ };
+
+ const serverResponse = {
+ body: {
+ bids: [
+ {
+ 'displayCode': 'test html',
+ 'id': '123456',
+ 'cpm': 375,
+ 'currency': 'RUB',
+ 'placementId': 'profileName',
+ 'codeType': 'js',
+ 'size': {
+ 'width': 640,
+ 'height': 480
+ }
+ }
+ ]
+ }
+ };
+
+ const bids = spec.interpretResponse(serverResponse, bidRequestData);
+ expect(bids).to.have.lengthOf(1);
+ const bid = bids[0];
+ expect(bid.requestId).to.equal('123456')
+ expect(bid.cpm).to.equal(375);
+ expect(bid.currency).to.equal('RUB');
+ expect(bid.width).to.equal(640);
+ expect(bid.height).to.equal(480);
+ expect(bid.ad).to.equal('test html');
+ expect(bid.creativeId).to.equal(`123456`)
+ expect(bid.netRevenue).to.equal(true);
+ });
+})
diff --git a/test/spec/modules/vidoomyBidAdapter_spec.js b/test/spec/modules/vidoomyBidAdapter_spec.js
index 8aa127faef2..61b7f2fad7d 100644
--- a/test/spec/modules/vidoomyBidAdapter_spec.js
+++ b/test/spec/modules/vidoomyBidAdapter_spec.js
@@ -95,7 +95,8 @@ describe('vidoomyBidAdapter', function() {
refererInfo: {
numIframes: 0,
reachedTop: true,
- referer: 'http://example.com',
+ domain: 'example.com',
+ page: 'http://example.com',
stack: ['http://example.com']
}
};
diff --git a/test/spec/modules/viewability_spec.js b/test/spec/modules/viewability_spec.js
deleted file mode 100644
index ab2753daf53..00000000000
--- a/test/spec/modules/viewability_spec.js
+++ /dev/null
@@ -1,280 +0,0 @@
-import { expect } from 'chai';
-import * as sinon from 'sinon';
-import * as utils from 'src/utils.js';
-import * as viewability from 'modules/viewability.js';
-
-describe('viewability test', () => {
- describe('start measurement', () => {
- let sandbox;
- let intersectionObserverStub;
- let setTimeoutStub;
- let observeCalled;
- let unobserveCalled;
- let ti = 1;
- beforeEach(() => {
- observeCalled = false;
- unobserveCalled = false;
- sandbox = sinon.sandbox.create();
-
- let fakeIntersectionObserver = (stateChange, options) => {
- return {
- observe: (element) => {
- observeCalled = true;
- stateChange([{ isIntersecting: true }]);
- },
- unobserve: (element) => {
- unobserveCalled = true;
- },
- };
- };
-
- intersectionObserverStub = sandbox.stub(window, 'IntersectionObserver').callsFake(fakeIntersectionObserver);
- setTimeoutStub = sandbox.stub(window, 'setTimeout').callsFake((callback, timeout) => {
- callback();
- return ti++;
- });
- });
-
- afterEach(() => {
- sandbox.restore();
- });
-
- it('should trigger appropriate callbacks', () => {
- viewability.startMeasurement('0', {}, { method: 'img', value: 'http://my.tracker/123' }, { inViewThreshold: 0.5, timeInView: 1000 });
-
- sinon.assert.called(intersectionObserverStub);
- sinon.assert.called(setTimeoutStub);
- expect(observeCalled).to.equal(true);
- expect(unobserveCalled).to.equal(true);
- });
-
- it('should trigger img tracker', () => {
- let triggerPixelSpy = sandbox.spy(utils, ['triggerPixel']);
- viewability.startMeasurement('1', {}, { method: 'img', value: 'http://my.tracker/123' }, { inViewThreshold: 0.5, timeInView: 1000 });
- expect(triggerPixelSpy.callCount).to.equal(1);
- });
-
- it('should trigger js tracker', () => {
- let insertHtmlIntoIframeSpy = sandbox.spy(utils, ['insertHtmlIntoIframe']);
- viewability.startMeasurement('2', {}, { method: 'js', value: 'http://my.tracker/123.js' }, { inViewThreshold: 0.5, timeInView: 1000 });
- expect(insertHtmlIntoIframeSpy.callCount).to.equal(1);
- });
-
- it('should trigger callback tracker', () => {
- let callbackFired = false;
- viewability.startMeasurement('3', {}, { method: 'callback', value: () => { callbackFired = true; } }, { inViewThreshold: 0.5, timeInView: 1000 });
- expect(callbackFired).to.equal(true);
- });
-
- it('should check for vid uniqueness', () => {
- let logWarnSpy = sandbox.spy(utils, 'logWarn');
- viewability.startMeasurement('4', {}, { method: 'js', value: 'http://my.tracker/123.js' }, { inViewThreshold: 0.5, timeInView: 1000 });
- expect(logWarnSpy.callCount).to.equal(0);
-
- viewability.startMeasurement('4', {}, { method: 'js', value: 'http://my.tracker/123.js' }, { inViewThreshold: 0.5, timeInView: 1000 });
- expect(logWarnSpy.callCount).to.equal(1);
- expect(logWarnSpy.calledWith(`${viewability.MODULE_NAME}: must provide an unregistered vid`, '4')).to.equal(true);
- });
-
- it('should check for valid criteria', () => {
- let logWarnSpy = sandbox.spy(utils, 'logWarn');
- viewability.startMeasurement('5', {}, { method: 'js', value: 'http://my.tracker/123.js' }, { timeInView: 1000 });
- expect(logWarnSpy.callCount).to.equal(1);
- expect(logWarnSpy.calledWith(`${viewability.MODULE_NAME}: missing criteria`, { timeInView: 1000 })).to.equal(true);
- });
-
- it('should check for valid tracker', () => {
- let logWarnSpy = sandbox.spy(utils, 'logWarn');
- viewability.startMeasurement('6', {}, { method: 'callback', value: 'string' }, { inViewThreshold: 0.5, timeInView: 1000 });
- expect(logWarnSpy.callCount).to.equal(1);
- expect(logWarnSpy.calledWith(`${viewability.MODULE_NAME}: invalid tracker`, { method: 'callback', value: 'string' })).to.equal(true);
- });
-
- it('should check if element provided', () => {
- let logWarnSpy = sandbox.spy(utils, 'logWarn');
- viewability.startMeasurement('7', undefined, { method: 'js', value: 'http://my.tracker/123.js' }, { timeInView: 1000 });
- expect(logWarnSpy.callCount).to.equal(1);
- expect(logWarnSpy.calledWith(`${viewability.MODULE_NAME}: no html element provided`)).to.equal(true);
- });
- });
-
- describe('stop measurement', () => {
- let sandbox;
- let intersectionObserverStub;
- let setTimeoutStub;
- let clearTimeoutStub;
- let observeCalled;
- let unobserveCalled;
- let stateChangeBackup;
- let ti = 1;
- beforeEach(() => {
- observeCalled = false;
- unobserveCalled = false;
- sandbox = sinon.sandbox.create();
-
- let fakeIntersectionObserver = (stateChange, options) => {
- return {
- observe: (element) => {
- stateChangeBackup = stateChange;
- observeCalled = true;
- stateChange([{ isIntersecting: true }]);
- },
- unobserve: (element) => {
- unobserveCalled = true;
- },
- };
- };
-
- intersectionObserverStub = sandbox.stub(window, 'IntersectionObserver').callsFake(fakeIntersectionObserver);
- setTimeoutStub = sandbox.stub(window, 'setTimeout').callsFake((callback, timeout) => {
- // skipping the callback
- return ti++;
- });
- clearTimeoutStub = sandbox.stub(window, 'clearTimeout').callsFake((timeoutId) => { });
- });
-
- afterEach(() => {
- sandbox.restore();
- });
-
- it('should clear the timeout', () => {
- viewability.startMeasurement('10', {}, { method: 'img', value: 'http://my.tracker/123' }, { inViewThreshold: 0.5, timeInView: 1000 });
- stateChangeBackup([{ isIntersecting: false }]);
- sinon.assert.called(intersectionObserverStub);
- sinon.assert.called(setTimeoutStub);
- sinon.assert.called(clearTimeoutStub);
- expect(observeCalled).to.equal(true);
- });
-
- it('should unobserve', () => {
- viewability.startMeasurement('11', {}, { method: 'img', value: 'http://my.tracker/123' }, { inViewThreshold: 0.5, timeInView: 1000 });
- sinon.assert.called(intersectionObserverStub);
- sinon.assert.called(setTimeoutStub);
- expect(observeCalled).to.equal(true);
- expect(unobserveCalled).to.equal(false);
-
- viewability.stopMeasurement('11');
- expect(unobserveCalled).to.equal(true);
- sinon.assert.called(clearTimeoutStub);
- });
-
- it('should check for vid existence', () => {
- let logWarnSpy = sandbox.spy(utils, 'logWarn');
- viewability.stopMeasurement('100');
- expect(logWarnSpy.callCount).to.equal(1);
- expect(logWarnSpy.calledWith(`${viewability.MODULE_NAME}: must provide a registered vid`, '100')).to.equal(true);
- });
- });
-
- describe('handle creative messages', () => {
- let sandbox;
- let intersectionObserverStub;
- let setTimeoutStub;
- let observeCalled;
- let unobserveCalled;
- let ti = 1;
- let getElementsByTagStub;
- let getElementByIdStub;
-
- let fakeContentWindow = {};
- beforeEach(() => {
- observeCalled = false;
- unobserveCalled = false;
- sandbox = sinon.sandbox.create();
-
- let fakeIntersectionObserver = (stateChange, options) => {
- return {
- observe: (element) => {
- observeCalled = true;
- stateChange([{ isIntersecting: true }]);
- },
- unobserve: (element) => {
- unobserveCalled = true;
- },
- };
- };
-
- intersectionObserverStub = sandbox.stub(window, 'IntersectionObserver').callsFake(fakeIntersectionObserver);
- setTimeoutStub = sandbox.stub(window, 'setTimeout').callsFake((callback, timeout) => {
- callback();
- return ti++;
- });
-
- getElementsByTagStub = sandbox.stub(document, 'getElementsByTagName').callsFake((tagName) => {
- return [{
- contentWindow: fakeContentWindow,
- }];
- });
- getElementByIdStub = sandbox.stub(document, 'getElementById').callsFake((id) => {
- return {};
- });
- });
-
- afterEach(() => {
- sandbox.restore();
- });
-
- it('should find element by contentWindow', () => {
- let viewabilityRecord = {
- vid: 1000,
- tracker: {
- value: 'http://my.tracker/123',
- method: 'img',
- },
- criteria: { inViewThreshold: 0.5, timeInView: 1000 },
- message: 'Prebid Viewability',
- action: 'startMeasurement',
- };
- let data = JSON.stringify(viewabilityRecord);
-
- viewability.receiveMessage({
- data: data,
- source: fakeContentWindow,
- });
-
- sinon.assert.called(getElementsByTagStub);
- sinon.assert.called(intersectionObserverStub);
- sinon.assert.called(setTimeoutStub);
- expect(observeCalled).to.equal(true);
- expect(unobserveCalled).to.equal(true);
- });
-
- it('should find element by id', () => {
- let viewabilityRecord = {
- vid: 1001,
- tracker: {
- value: 'http://my.tracker/123',
- method: 'img',
- },
- criteria: { inViewThreshold: 0.5, timeInView: 1000 },
- message: 'Prebid Viewability',
- action: 'startMeasurement',
- elementId: '1',
- };
- let data = JSON.stringify(viewabilityRecord);
- viewability.receiveMessage({
- data: data,
- });
-
- sinon.assert.called(getElementByIdStub);
- sinon.assert.called(intersectionObserverStub);
- sinon.assert.called(setTimeoutStub);
- expect(observeCalled).to.equal(true);
- expect(unobserveCalled).to.equal(true);
- });
-
- it('should stop measurement', () => {
- let viewabilityRecord = {
- vid: 1001,
- message: 'Prebid Viewability',
- action: 'stopMeasurement',
- };
- let data = JSON.stringify(viewabilityRecord);
- viewability.receiveMessage({
- data: data,
- });
-
- expect(unobserveCalled).to.equal(true);
- });
- });
-});
diff --git a/test/spec/modules/visxBidAdapter_spec.js b/test/spec/modules/visxBidAdapter_spec.js
index 4aaaf996f58..b8a66e7c3b9 100755
--- a/test/spec/modules/visxBidAdapter_spec.js
+++ b/test/spec/modules/visxBidAdapter_spec.js
@@ -85,10 +85,10 @@ describe('VisxAdapter', function () {
const bidderRequest = {
timeout: 3000,
refererInfo: {
- referer: 'https://example.com'
+ page: 'https://example.com'
}
};
- const referrer = bidderRequest.refererInfo.referer;
+ const referrer = bidderRequest.refererInfo.page;
const schainObject = {
ver: '1.0',
nodes: [
@@ -425,10 +425,10 @@ describe('VisxAdapter', function () {
const bidderRequest = {
timeout: 3000,
refererInfo: {
- referer: 'https://example.com'
+ page: 'https://example.com'
}
};
- const referrer = bidderRequest.refererInfo.referer;
+ const referrer = bidderRequest.refererInfo.page;
const bidRequests = [
{
'bidder': 'visx',
@@ -489,10 +489,10 @@ describe('VisxAdapter', function () {
const bidderRequest = {
timeout: 3000,
refererInfo: {
- referer: 'https://example.com'
+ page: 'https://example.com'
}
};
- const referrer = bidderRequest.refererInfo.referer;
+ const referrer = bidderRequest.refererInfo.page;
const bidRequests = [
{
'bidder': 'visx',
diff --git a/test/spec/modules/voxBidAdapter_spec.js b/test/spec/modules/voxBidAdapter_spec.js
index 6906c7dbba4..923b0465e6c 100644
--- a/test/spec/modules/voxBidAdapter_spec.js
+++ b/test/spec/modules/voxBidAdapter_spec.js
@@ -15,7 +15,7 @@ function getSlotConfigs(mediaTypes, params) {
describe('VOX Adapter', function() {
const PLACE_ID = '5af45ad34d506ee7acad0c26';
const bidderRequest = {
- refererInfo: { referer: 'referer' }
+ refererInfo: { page: 'referer' }
}
const bannerMandatoryParams = {
placementId: PLACE_ID,
diff --git a/test/spec/modules/vrtcalBidAdapter_spec.js b/test/spec/modules/vrtcalBidAdapter_spec.js
index 66440130860..2f9f1b96142 100644
--- a/test/spec/modules/vrtcalBidAdapter_spec.js
+++ b/test/spec/modules/vrtcalBidAdapter_spec.js
@@ -1,6 +1,7 @@
import { expect } from 'chai'
import { spec } from 'modules/vrtcalBidAdapter'
import { newBidder } from 'src/adapters/bidderFactory'
+import { config } from 'src/config.js';
describe('vrtcalBidAdapter', function () {
const adapter = newBidder(spec)
@@ -50,6 +51,22 @@ describe('vrtcalBidAdapter', function () {
request = spec.buildRequests(bidRequests);
expect(request[0].data).to.match(/"bidfloor":0.55/);
});
+
+ it('pass GDPR,CCPA, and COPPA indicators/consent strings with the request when present', function () {
+ bidRequests[0].gdprConsent = {consentString: 'gdpr-consent-string', gdprApplies: true};
+ bidRequests[0].uspConsent = 'ccpa-consent-string';
+ config.setConfig({ coppa: false });
+
+ request = spec.buildRequests(bidRequests);
+ expect(request[0].data).to.match(/"user":{"ext":{"consent":"gdpr-consent-string"}}/);
+ expect(request[0].data).to.match(/"regs":{"coppa":0,"ext":{"gdpr":1,"us_privacy":"ccpa-consent-string"}}/);
+ });
+
+ it('pass bidder timeout/tmax with the request', function () {
+ config.setConfig({ bidderTimeout: 435 });
+ request = spec.buildRequests(bidRequests);
+ expect(request[0].data).to.match(/"tmax":435/);
+ });
});
describe('interpretResponse', function () {
diff --git a/test/spec/modules/weboramaRtdProvider_spec.js b/test/spec/modules/weboramaRtdProvider_spec.js
index 4dff3db5c18..523406dc492 100644
--- a/test/spec/modules/weboramaRtdProvider_spec.js
+++ b/test/spec/modules/weboramaRtdProvider_spec.js
@@ -88,6 +88,10 @@ describe('weboramaRtdProvider', function() {
};
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {}
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -132,7 +136,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
inventory: data
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: data
@@ -195,6 +199,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -252,7 +260,7 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[1].params).to.be.undefined;
expect(adUnit.bids[2].params.keywords).to.deep.equal(data);
expect(adUnit.bids[3].params).to.be.undefined;
- expect(adUnit.bids[4].ortb2).to.be.undefined;
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
});
expect(onDataResponse).to.deep.equal({
@@ -304,6 +312,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -407,6 +419,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -511,7 +527,7 @@ describe('weboramaRtdProvider', function() {
}
});
- expect(adUnit.bids[4].ortb2).to.be.undefined;
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
});
});
});
@@ -545,6 +561,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -649,7 +669,7 @@ describe('weboramaRtdProvider', function() {
}
});
- expect(adUnit.bids[4].ortb2).to.be.undefined;
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
});
});
});
@@ -680,6 +700,9 @@ describe('weboramaRtdProvider', function() {
};
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {}
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -739,6 +762,10 @@ describe('weboramaRtdProvider', function() {
};
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {}
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -812,7 +839,7 @@ describe('weboramaRtdProvider', function() {
baz: 'bam',
}
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: data
@@ -845,6 +872,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {}
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -888,7 +919,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
inventory: defaultProfile
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: defaultProfile
@@ -941,6 +972,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -1003,7 +1038,7 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[3].params).to.deep.equal({
inventory: data
});
- expect(adUnit.bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: data
@@ -1062,6 +1097,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -1097,7 +1136,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
visitor: data
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
user: {
ext: {
data: data
@@ -1168,6 +1207,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -1216,8 +1259,8 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[1].params).to.be.undefined;
expect(adUnit.bids[2].params.keywords).to.deep.equal(data);
expect(adUnit.bids[3].params).to.be.undefined;
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
expect(onDataResponse).to.deep.equal({
data: data,
@@ -1276,6 +1319,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -1323,8 +1370,8 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[0].params).to.be.undefined;
expect(adUnit.bids[1].params).to.be.undefined;
expect(adUnit.bids[3].params).to.be.undefined;
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
expect(reqBidsConfigObj.adUnits[0].bids[2].params.keywords).to.deep.equal(data);
expect(reqBidsConfigObj.adUnits[1].bids[2].params).to.be.undefined;
@@ -1379,6 +1426,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -1474,8 +1525,8 @@ describe('weboramaRtdProvider', function() {
baz: 'bam'
}
});
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
});
});
});
@@ -1517,6 +1568,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -1612,8 +1667,8 @@ describe('weboramaRtdProvider', function() {
baz: 'bam'
}
});
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
});
});
});
@@ -1712,6 +1767,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {}
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -1777,7 +1836,7 @@ describe('weboramaRtdProvider', function() {
webo_audiences: ['baz'],
}
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
user: {
ext: {
data: data
@@ -1804,6 +1863,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {}
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -1839,7 +1902,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
visitor: defaultProfile
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
user: {
ext: {
data: defaultProfile
@@ -1873,6 +1936,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {}
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -1908,7 +1975,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
visitor: defaultProfile
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
user: {
ext: {
data: defaultProfile
@@ -1970,6 +2037,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -2024,7 +2095,7 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[3].params).to.deep.equal({
visitor: data
});
- expect(adUnit.bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
user: {
ext: {
data: data
@@ -2082,6 +2153,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -2117,7 +2192,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
inventory: data,
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: data,
@@ -2187,6 +2262,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -2235,8 +2314,8 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[1].params).to.be.undefined;
expect(adUnit.bids[2].params.keywords).to.deep.equal(data);
expect(adUnit.bids[3].params).to.be.undefined;
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
expect(onDataResponse).to.deep.equal({
data: data,
@@ -2294,6 +2373,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -2341,8 +2424,8 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[0].params).to.be.undefined;
expect(adUnit.bids[1].params).to.be.undefined;
expect(adUnit.bids[3].params).to.be.undefined;
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
expect(reqBidsConfigObj.adUnits[0].bids[2].params.keywords).to.deep.equal(data);
expect(reqBidsConfigObj.adUnits[1].bids[2].params).to.be.undefined;
@@ -2396,6 +2479,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -2491,8 +2578,8 @@ describe('weboramaRtdProvider', function() {
baz: 'bam'
}
});
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
});
});
});
@@ -2533,6 +2620,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -2628,8 +2719,8 @@ describe('weboramaRtdProvider', function() {
baz: 'bam'
}
});
- expect(adUnit.bids[4].ortb2).to.be.undefined;
});
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.be.undefined;
});
});
});
@@ -2667,6 +2758,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -2726,6 +2821,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -2791,7 +2890,7 @@ describe('weboramaRtdProvider', function() {
baz: 'bam',
}
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: data,
@@ -2817,6 +2916,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -2852,7 +2955,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
inventory: defaultProfile,
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: defaultProfile,
@@ -2885,6 +2988,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode = 'adunit1';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode,
bids: [{
@@ -2920,7 +3027,7 @@ describe('weboramaRtdProvider', function() {
expect(reqBidsConfigObj.adUnits[0].bids[3].params).to.deep.equal({
inventory: defaultProfile,
});
- expect(reqBidsConfigObj.adUnits[0].bids[4].ortb2).to.deep.equal({
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
site: {
ext: {
data: defaultProfile,
@@ -2981,6 +3088,10 @@ describe('weboramaRtdProvider', function() {
const adUnitCode1 = 'adunit1';
const adUnitCode2 = 'adunit2';
const reqBidsConfigObj = {
+ ortb2Fragments: {
+ global: {},
+ bidder: {},
+ },
adUnits: [{
code: adUnitCode1,
bids: [{
@@ -3035,13 +3146,13 @@ describe('weboramaRtdProvider', function() {
expect(adUnit.bids[3].params).to.deep.equal({
inventory: data,
});
- expect(adUnit.bids[4].ortb2).to.deep.equal({
- site: {
- ext: {
- data: data,
- },
+ });
+ expect(reqBidsConfigObj.ortb2Fragments.bidder.other).to.deep.equal({
+ site: {
+ ext: {
+ data: data,
},
- });
+ },
});
expect(reqBidsConfigObj.adUnits[0].bids[2].params.keywords).to.deep.equal({
diff --git a/test/spec/modules/winrBidAdapter_spec.js b/test/spec/modules/winrBidAdapter_spec.js
index 03e441df727..174f600fa06 100644
--- a/test/spec/modules/winrBidAdapter_spec.js
+++ b/test/spec/modules/winrBidAdapter_spec.js
@@ -434,7 +434,7 @@ describe('WinrAdapter', function () {
const bidRequest = Object.assign({}, bidRequests[0])
const bidderRequest = {
refererInfo: {
- referer: 'https://example.com/page.html',
+ topmostLocation: 'https://example.com/page.html',
reachedTop: true,
numIframes: 2,
stack: [
@@ -563,11 +563,7 @@ describe('WinrAdapter', function () {
uid2: { id: 'sample-uid2-value' },
criteoId: 'sample-criteo-userid',
netId: 'sample-netId-userid',
- idl_env: 'sample-idl-userid',
- flocId: {
- id: 'sample-flocid-value',
- version: 'chrome.1.0'
- }
+ idl_env: 'sample-idl-userid'
}
});
@@ -584,11 +580,6 @@ describe('WinrAdapter', function () {
id: 'sample-criteo-userid',
});
- expect(payload.eids).to.deep.include({
- source: 'chrome.com',
- id: 'sample-flocid-value'
- });
-
expect(payload.eids).to.deep.include({
source: 'netid.de',
id: 'sample-netId-userid',
diff --git a/test/spec/modules/xeBidAdapter_spec.js b/test/spec/modules/xeBidAdapter_spec.js
new file mode 100644
index 00000000000..dcd82683221
--- /dev/null
+++ b/test/spec/modules/xeBidAdapter_spec.js
@@ -0,0 +1,450 @@
+import { expect } from 'chai';
+import { config } from 'src/config.js';
+import { spec, getBidFloor } from 'modules/xeBidAdapter.js';
+import { deepClone } from 'src/utils';
+import { createEidsArray } from 'modules/userId/eids.js';
+
+const ENDPOINT = 'https://pbjs.xe.works/bid';
+
+const defaultRequest = {
+ adUnitCode: 'test',
+ bidId: '1',
+ requestId: 'qwerty',
+ auctionId: 'auctionId',
+ transactionId: 'tr1',
+ mediaTypes: {
+ banner: {
+ sizes: [
+ [300, 250],
+ [300, 200]
+ ]
+ }
+ },
+ bidder: 'xe',
+ params: {
+ env: 'xe',
+ placement: 'test-banner',
+ ext: {}
+ },
+ bidRequestsCount: 1
+};
+
+const defaultRequestVideo = deepClone(defaultRequest);
+defaultRequestVideo.mediaTypes = {
+ video: {
+ playerSize: [640, 480],
+ context: 'instream',
+ skipppable: true
+ }
+};
+
+describe('isBidRequestValid', function () {
+ it('should return false when request params is missing', function () {
+ const invalidRequest = deepClone(defaultRequest);
+ delete invalidRequest.params;
+ expect(spec.isBidRequestValid(invalidRequest)).to.equal(false);
+ });
+
+ it('should return false when required env param is missing', function () {
+ const invalidRequest = deepClone(defaultRequest);
+ delete invalidRequest.params.env;
+ expect(spec.isBidRequestValid(invalidRequest)).to.equal(false);
+ });
+
+ it('should return false when required placement param is missing', function () {
+ const invalidRequest = deepClone(defaultRequest);
+ delete invalidRequest.params.placement;
+ expect(spec.isBidRequestValid(invalidRequest)).to.equal(false);
+ });
+
+ it('should return false when video.playerSize is missing', function () {
+ const invalidRequest = deepClone(defaultRequestVideo);
+ delete invalidRequest.mediaTypes.video.playerSize;
+ expect(spec.isBidRequestValid(invalidRequest)).to.equal(false);
+ });
+
+ it('should return true when required params found', function () {
+ expect(spec.isBidRequestValid(defaultRequest)).to.equal(true);
+ });
+});
+
+describe('buildRequests', function () {
+ beforeEach(function () {
+ config.resetConfig();
+ });
+
+ it('should send request with correct structure', function () {
+ const request = spec.buildRequests([defaultRequest], {});
+ expect(request.method).to.equal('POST');
+ expect(request.url).to.equal(ENDPOINT);
+ expect(request.options).to.have.property('contentType').and.to.equal('application/json');
+ expect(request).to.have.property('data');
+ });
+
+ it('should build basic request structure', function () {
+ const request = JSON.parse(spec.buildRequests([defaultRequest], {}).data)[0];
+ expect(request).to.have.property('bidId').and.to.equal(defaultRequest.bidId);
+ expect(request).to.have.property('auctionId').and.to.equal(defaultRequest.auctionId);
+ expect(request).to.have.property('transactionId').and.to.equal(defaultRequest.transactionId);
+ expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset());
+ expect(request).to.have.property('bc').and.to.equal(1);
+ expect(request).to.have.property('floor').and.to.equal(null);
+ expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] });
+ expect(request).to.have.property('gdprApplies').and.to.equal(0);
+ expect(request).to.have.property('consentString').and.to.equal('');
+ expect(request).to.have.property('userEids').and.to.deep.equal([]);
+ expect(request).to.have.property('usPrivacy').and.to.equal('');
+ expect(request).to.have.property('coppa').and.to.equal(0);
+ expect(request).to.have.property('sizes').and.to.deep.equal(['300x250', '300x200']);
+ expect(request).to.have.property('ext').and.to.deep.equal({});
+ expect(request).to.have.property('env').and.to.deep.equal({
+ env: 'xe',
+ placement: 'test-banner'
+ });
+ expect(request).to.have.property('device').and.to.deep.equal({
+ ua: navigator.userAgent,
+ lang: navigator.language
+ });
+ });
+
+ it('should build request with schain', function () {
+ const schainRequest = deepClone(defaultRequest);
+ schainRequest.schain = {
+ validation: 'strict',
+ config: {
+ ver: '1.0'
+ }
+ };
+ const request = JSON.parse(spec.buildRequests([schainRequest], {}).data)[0];
+ expect(request).to.have.property('schain').and.to.deep.equal({
+ validation: 'strict',
+ config: {
+ ver: '1.0'
+ }
+ });
+ });
+
+ it('should build request with location', function () {
+ const bidderRequest = {
+ refererInfo: {
+ page: 'page',
+ location: 'location',
+ domain: 'domain',
+ ref: 'ref',
+ isAmp: false
+ }
+ };
+ const request = JSON.parse(spec.buildRequests([defaultRequest], bidderRequest).data)[0];
+ expect(request).to.have.property('location');
+ const location = request.location;
+ expect(location).to.have.property('page').and.to.equal('page');
+ expect(location).to.have.property('location').and.to.equal('location');
+ expect(location).to.have.property('domain').and.to.equal('domain');
+ expect(location).to.have.property('ref').and.to.equal('ref');
+ expect(location).to.have.property('isAmp').and.to.equal(false);
+ });
+
+ it('should build request with ortb2 info', function () {
+ const ortb2Request = deepClone(defaultRequest);
+ ortb2Request.ortb2 = {
+ site: {
+ name: 'name'
+ }
+ };
+ const request = JSON.parse(spec.buildRequests([ortb2Request], {}).data)[0];
+ expect(request).to.have.property('ortb2').and.to.deep.equal({
+ site: {
+ name: 'name'
+ }
+ });
+ });
+
+ it('should build request with ortb2Imp info', function () {
+ const ortb2ImpRequest = deepClone(defaultRequest);
+ ortb2ImpRequest.ortb2Imp = {
+ ext: {
+ data: {
+ pbadslot: 'home1',
+ adUnitSpecificAttribute: '1'
+ }
+ }
+ };
+ const request = JSON.parse(spec.buildRequests([ortb2ImpRequest], {}).data)[0];
+ expect(request).to.have.property('ortb2Imp').and.to.deep.equal({
+ ext: {
+ data: {
+ pbadslot: 'home1',
+ adUnitSpecificAttribute: '1'
+ }
+ }
+ });
+ });
+
+ it('should build request with valid bidfloor', function () {
+ const bfRequest = deepClone(defaultRequest);
+ bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' });
+ const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0];
+ expect(request).to.have.property('floor').and.to.equal(5);
+ });
+
+ it('should build request with gdpr consent data if applies', function () {
+ const bidderRequest = {
+ gdprConsent: {
+ gdprApplies: true,
+ consentString: 'qwerty'
+ }
+ };
+ const request = JSON.parse(spec.buildRequests([defaultRequest], bidderRequest).data)[0];
+ expect(request).to.have.property('gdprApplies').and.equals(1);
+ expect(request).to.have.property('consentString').and.equals('qwerty');
+ });
+
+ it('should build request with usp consent data if applies', function () {
+ const bidderRequest = {
+ uspConsent: '1YA-'
+ };
+ const request = JSON.parse(spec.buildRequests([defaultRequest], bidderRequest).data)[0];
+ expect(request).to.have.property('usPrivacy').and.equals('1YA-');
+ });
+
+ it('should build request with coppa 1', function () {
+ config.setConfig({
+ coppa: true
+ });
+ const request = JSON.parse(spec.buildRequests([defaultRequest], {}).data)[0];
+ expect(request).to.have.property('coppa').and.equals(1);
+ });
+
+ it('should build request with extended ids', function () {
+ const idRequest = deepClone(defaultRequest);
+ idRequest.userIdAsEids = createEidsArray({
+ tdid: 'TTD_ID_FROM_USER_ID_MODULE',
+ pubcid: 'pubCommonId_FROM_USER_ID_MODULE'
+ });
+ const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0];
+ expect(request).to.have.property('userEids').and.deep.equal([
+ { source: 'adserver.org', uids: [ { id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } } ] },
+ { source: 'pubcid.org', uids: [ { id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 } ] }
+ ]);
+ });
+
+ it('should build request with video', function () {
+ const request = JSON.parse(spec.buildRequests([defaultRequestVideo], {}).data)[0];
+ expect(request).to.have.property('video').and.to.deep.equal({
+ playerSize: [640, 480],
+ context: 'instream',
+ skipppable: true
+ });
+ expect(request).to.have.property('sizes').and.to.deep.equal(['640x480']);
+ });
+});
+
+describe('interpretResponse', function () {
+ it('should return empty bids', function () {
+ const serverResponse = {
+ body: {
+ data: null
+ }
+ };
+
+ const invalidResponse = spec.interpretResponse(serverResponse, {});
+ expect(invalidResponse).to.be.an('array').that.is.empty;
+ });
+
+ it('should interpret valid response', function () {
+ const serverResponse = {
+ body: {
+ data: [{
+ requestId: 'qwerty',
+ cpm: 1,
+ currency: 'USD',
+ width: 300,
+ height: 250,
+ ttl: 600,
+ meta: {
+ advertiserDomains: ['xe.works']
+ },
+ ext: {
+ pixels: [
+ [ 'iframe', 'surl1' ],
+ [ 'image', 'surl2' ],
+ ]
+ }
+ }]
+ }
+ };
+
+ const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequest });
+ const bid = validResponse[0];
+ expect(validResponse).to.be.an('array').that.is.not.empty;
+ expect(bid.requestId).to.equal('qwerty');
+ expect(bid.cpm).to.equal(1);
+ expect(bid.currency).to.equal('USD');
+ expect(bid.width).to.equal(300);
+ expect(bid.height).to.equal(250);
+ expect(bid.ttl).to.equal(600);
+ expect(bid.meta).to.deep.equal({ advertiserDomains: ['xe.works'] });
+ });
+
+ it('should interpret valid banner response', function () {
+ const serverResponse = {
+ body: {
+ data: [{
+ requestId: 'qwerty',
+ cpm: 1,
+ currency: 'USD',
+ width: 300,
+ height: 250,
+ ttl: 600,
+ mediaType: 'banner',
+ creativeId: 'xe-demo-banner',
+ ad: 'ad',
+ meta: {}
+ }]
+ }
+ };
+
+ const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequest });
+ const bid = validResponseBanner[0];
+ expect(validResponseBanner).to.be.an('array').that.is.not.empty;
+ expect(bid.mediaType).to.equal('banner');
+ expect(bid.creativeId).to.equal('xe-demo-banner');
+ expect(bid.ad).to.equal('ad');
+ });
+
+ it('should interpret valid video response', function () {
+ const serverResponse = {
+ body: {
+ data: [{
+ requestId: 'qwerty',
+ cpm: 1,
+ currency: 'USD',
+ width: 600,
+ height: 480,
+ ttl: 600,
+ mediaType: 'video',
+ creativeId: 'xe-demo-video',
+ ad: 'vast-xml',
+ meta: {}
+ }]
+ }
+ };
+
+ const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequestVideo });
+ const bid = validResponseBanner[0];
+ expect(validResponseBanner).to.be.an('array').that.is.not.empty;
+ expect(bid.mediaType).to.equal('video');
+ expect(bid.creativeId).to.equal('xe-demo-video');
+ expect(bid.ad).to.equal('vast-xml');
+ });
+});
+
+describe('getUserSyncs', function () {
+ it('shoukd handle no params', function () {
+ const opts = spec.getUserSyncs({}, []);
+ expect(opts).to.be.an('array').that.is.empty;
+ });
+
+ it('should return empty if sync is not allowed', function () {
+ const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false});
+ expect(opts).to.be.an('array').that.is.empty;
+ });
+
+ it('should allow iframe sync', function () {
+ const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [{
+ body: {
+ data: [{
+ requestId: 'qwerty',
+ ext: {
+ pixels: [
+ [ 'iframe', 'surl1?a=b' ],
+ [ 'image', 'surl2?a=b' ],
+ ]
+ }
+ }]
+ }
+ }]);
+ expect(opts.length).to.equal(1);
+ expect(opts[0].type).to.equal('iframe');
+ expect(opts[0].url).to.equal('surl1?a=b&us_privacy=&gdpr=0&gdpr_consent=');
+ });
+
+ it('should allow pixel sync', function () {
+ const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{
+ body: {
+ data: [{
+ requestId: 'qwerty',
+ ext: {
+ pixels: [
+ [ 'iframe', 'surl1?a=b' ],
+ [ 'image', 'surl2?a=b' ],
+ ]
+ }
+ }]
+ }
+ }]);
+ expect(opts.length).to.equal(1);
+ expect(opts[0].type).to.equal('image');
+ expect(opts[0].url).to.equal('surl2?a=b&us_privacy=&gdpr=0&gdpr_consent=');
+ });
+
+ it('should allow pixel sync and parse consent params', function () {
+ const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{
+ body: {
+ data: [{
+ requestId: 'qwerty',
+ ext: {
+ pixels: [
+ [ 'iframe', 'surl1?a=b' ],
+ [ 'image', 'surl2?a=b' ],
+ ]
+ }
+ }]
+ }
+ }], {
+ gdprApplies: 1,
+ consentString: '1YA-'
+ });
+ expect(opts.length).to.equal(1);
+ expect(opts[0].type).to.equal('image');
+ expect(opts[0].url).to.equal('surl2?a=b&us_privacy=&gdpr=1&gdpr_consent=1YA-');
+ });
+});
+
+describe('getBidFloor', function () {
+ it('should return null when getFloor is not a function', () => {
+ const bid = { getFloor: 2 };
+ const result = getBidFloor(bid);
+ expect(result).to.be.null;
+ });
+
+ it('should return null when getFloor doesnt return an object', () => {
+ const bid = { getFloor: () => 2 };
+ const result = getBidFloor(bid);
+ expect(result).to.be.null;
+ });
+
+ it('should return null when floor is not a number', () => {
+ const bid = {
+ getFloor: () => ({ floor: 'string', currency: 'USD' })
+ };
+ const result = getBidFloor(bid);
+ expect(result).to.be.null;
+ });
+
+ it('should return null when currency is not USD', () => {
+ const bid = {
+ getFloor: () => ({ floor: 5, currency: 'EUR' })
+ };
+ const result = getBidFloor(bid);
+ expect(result).to.be.null;
+ });
+
+ it('should return floor value when everything is correct', () => {
+ const bid = {
+ getFloor: () => ({ floor: 5, currency: 'USD' })
+ };
+ const result = getBidFloor(bid);
+ expect(result).to.equal(5);
+ });
+});
diff --git a/test/spec/modules/yahoosspBidAdapter_spec.js b/test/spec/modules/yahoosspBidAdapter_spec.js
index e301218741c..6e52e9c57db 100644
--- a/test/spec/modules/yahoosspBidAdapter_spec.js
+++ b/test/spec/modules/yahoosspBidAdapter_spec.js
@@ -16,7 +16,7 @@ const PREBID_VERSION = '$prebid.version$';
const INTEGRATION_METHOD = 'prebid.js';
// Utility functions
-const generateBidRequest = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObject, videoContext, pubIdMode}) => {
+const generateBidRequest = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObject, videoContext, pubIdMode, ortb2}) => {
const bidRequest = {
adUnitCode,
auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917',
@@ -30,7 +30,8 @@ const generateBidRequest = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObje
bidOverride: bidOverrideObject
},
src: 'client',
- transactionId: '5b17b67d-7704-4732-8cc9-5b1723e9bcf9'
+ transactionId: '5b17b67d-7704-4732-8cc9-5b1723e9bcf9',
+ ortb2
};
const bannerObj = {
@@ -71,7 +72,7 @@ const generateBidRequest = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObje
return bidRequest;
}
-let generateBidderRequest = (bidRequestArray, adUnitCode) => {
+let generateBidderRequest = (bidRequestArray, adUnitCode, ortb2 = {}) => {
const bidderRequest = {
adUnitCode: adUnitCode || 'default-adUnitCode',
auctionId: 'd4c83a3b-18e4-4208-b98b-63848449c7aa',
@@ -80,7 +81,7 @@ let generateBidderRequest = (bidRequestArray, adUnitCode) => {
bidderRequestId: '112f1c7c5d399a',
bids: bidRequestArray,
refererInfo: {
- referer: 'https://publisher-test.com',
+ page: 'https://publisher-test.com',
reachedTop: true,
isAmp: false,
numIframes: 0,
@@ -93,12 +94,13 @@ let generateBidderRequest = (bidRequestArray, adUnitCode) => {
},
start: new Date().getTime(),
timeout: 1000,
+ ortb2
};
return bidderRequest;
};
-const generateBuildRequestMock = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObject, videoContext, pubIdMode}) => {
+const generateBuildRequestMock = ({bidId, pos, adUnitCode, adUnitType, bidOverrideObject, videoContext, pubIdMode, ortb2}) => {
const bidRequestConfig = {
bidId: bidId || DEFAULT_BID_ID,
pos: pos || DEFAULT_BID_POS,
@@ -106,11 +108,12 @@ const generateBuildRequestMock = ({bidId, pos, adUnitCode, adUnitType, bidOverri
adUnitType: adUnitType || DEFAULT_AD_UNIT_TYPE,
bidOverrideObject: bidOverrideObject || DEFAULT_PARAMS_BID_OVERRIDE,
videoContext: videoContext || DEFAULT_VIDEO_CONTEXT,
- pubIdMode: pubIdMode || false
+ pubIdMode: pubIdMode || false,
+ ortb2: ortb2 || {}
};
const bidRequest = generateBidRequest(bidRequestConfig);
const validBidRequests = [bidRequest];
- const bidderRequest = generateBidderRequest(validBidRequests, adUnitCode);
+ const bidderRequest = generateBidderRequest(validBidRequests, adUnitCode, ortb2);
return { bidRequest, validBidRequests, bidderRequest }
};
@@ -331,6 +334,19 @@ describe('YahooSSP Bid Adapter:', () => {
});
describe('Schain module support:', () => {
+ it('should not include schain data when schain array is empty', function () {
+ const { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const globalSchain = {
+ ver: '1.0',
+ complete: 1,
+ nodes: []
+ };
+ bidRequest.schain = globalSchain;
+ const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
+ const schain = data.source.ext.schain;
+ expect(schain).to.be.undefined;
+ });
+
it('should send Global or Bidder specific schain', function () {
const { bidRequest, validBidRequests, bidderRequest } = generateBuildRequestMock({});
const globalSchain = {
@@ -355,10 +371,9 @@ describe('YahooSSP Bid Adapter:', () => {
// Should not allow invalid "site" data types
const INVALID_ORTB2_TYPES = [ null, [], 123, 'unsupportedKeyName', true, false, undefined ];
INVALID_ORTB2_TYPES.forEach(param => {
- const ortb2 = { site: param }
- config.setConfig({ortb2});
it(`should not allow invalid site types to be added to bid-request: ${JSON.stringify(param)}`, () => {
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const ortb2 = { site: param }
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site[param]).to.be.undefined;
});
@@ -375,8 +390,7 @@ describe('YahooSSP Bid Adapter:', () => {
[param]: 'something'
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site[param]).to.exist;
expect(data.site[param]).to.be.a('string');
@@ -391,8 +405,7 @@ describe('YahooSSP Bid Adapter:', () => {
[param]: ['something']
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site[param]).to.exist;
expect(data.site[param]).to.be.a('array');
@@ -408,8 +421,7 @@ describe('YahooSSP Bid Adapter:', () => {
content: param
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site.content).to.be.undefined;
});
@@ -426,8 +438,7 @@ describe('YahooSSP Bid Adapter:', () => {
}
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site.content).to.be.a('object');
});
@@ -443,8 +454,7 @@ describe('YahooSSP Bid Adapter:', () => {
}
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site.content[param]).to.exist;
expect(data.site.content[param]).to.be.a('string');
@@ -462,8 +472,7 @@ describe('YahooSSP Bid Adapter:', () => {
}
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site.content[param]).to.be.a('number');
expect(data.site.content[param]).to.be.equal(ortb2.site.content[param]);
@@ -480,8 +489,7 @@ describe('YahooSSP Bid Adapter:', () => {
}
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site.content[param]).to.be.a('array');
expect(data.site.content[param]).to.be.equal(ortb2.site.content[param]);
@@ -498,8 +506,7 @@ describe('YahooSSP Bid Adapter:', () => {
}
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.site.content[param]).to.be.a('object');
expect(data.site.content[param]).to.be.equal(ortb2.site.content[param]);
@@ -513,10 +520,9 @@ describe('YahooSSP Bid Adapter:', () => {
// Should not allow invalid "user" data types
const INVALID_ORTB2_TYPES = [ null, [], 'unsupportedKeyName', true, false, undefined ];
INVALID_ORTB2_TYPES.forEach(param => {
- const ortb2 = { user: param }
- config.setConfig({ortb2});
it(`should not allow invalid site types to be added to bid-request: ${JSON.stringify(param)}`, () => {
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const ortb2 = { user: param }
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user[param]).to.be.undefined;
});
@@ -531,8 +537,7 @@ describe('YahooSSP Bid Adapter:', () => {
[param]: 'something'
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user[param]).to.exist;
expect(data.user[param]).to.be.a('string');
@@ -548,8 +553,7 @@ describe('YahooSSP Bid Adapter:', () => {
[param]: 1982
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user[param]).to.exist;
expect(data.user[param]).to.be.a('number');
@@ -565,8 +569,7 @@ describe('YahooSSP Bid Adapter:', () => {
[param]: ['something']
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user[param]).to.exist;
expect(data.user[param]).to.be.a('array');
@@ -582,8 +585,7 @@ describe('YahooSSP Bid Adapter:', () => {
[param]: {a: '123', b: '456'}
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user[param]).to.be.a('object');
expect(data.user[param]).to.be.deep.include({[param]: {a: '123', b: '456'}});
@@ -605,8 +607,7 @@ describe('YahooSSP Bid Adapter:', () => {
}
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user.data[0][param]).to.exist;
expect(data.user.data[0][param]).to.be.a('string');
@@ -625,8 +626,7 @@ describe('YahooSSP Bid Adapter:', () => {
data: [{[param]: [{id: 1}]}]
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user.data[0][param]).to.exist;
expect(data.user.data[0][param]).to.be.a('array');
@@ -642,8 +642,7 @@ describe('YahooSSP Bid Adapter:', () => {
data: [{[param]: {id: 'ext'}}]
}
};
- config.setConfig({ortb2});
- const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ const { validBidRequests, bidderRequest } = generateBuildRequestMock({ortb2});
const data = spec.buildRequests(validBidRequests, bidderRequest)[0].data;
expect(data.user.data[0][param]).to.exist;
expect(data.user.data[0][param]).to.be.a('object');
@@ -823,6 +822,7 @@ describe('YahooSSP Bid Adapter:', () => {
describe('Request Headers validation:', () => {
it('should return request objects with the relevant custom headers and content type declaration', () => {
const { validBidRequests, bidderRequest } = generateBuildRequestMock({});
+ bidderRequest.gdprConsent.gdprApplies = false;
const options = spec.buildRequests(validBidRequests, bidderRequest).options;
expect(options).to.deep.equal(
{
@@ -841,7 +841,7 @@ describe('YahooSSP Bid Adapter:', () => {
const data = spec.buildRequests(validBidRequests, bidderRequest).data;
expect(data.site).to.deep.equal({
id: bidderRequest.bids[0].params.dcn,
- page: bidderRequest.refererInfo.referer
+ page: bidderRequest.refererInfo.page
});
expect(data.device).to.deep.equal({
diff --git a/test/spec/modules/yandexBidAdapter_spec.js b/test/spec/modules/yandexBidAdapter_spec.js
index 833f883fb7c..f4b15d6dbc4 100644
--- a/test/spec/modules/yandexBidAdapter_spec.js
+++ b/test/spec/modules/yandexBidAdapter_spec.js
@@ -56,8 +56,6 @@ describe('Yandex adapter', function () {
});
describe('buildRequests', function () {
- const refererUrl = 'https://yandex.ru/secure-ads';
-
const gdprConsent = {
gdprApplies: 1,
consentString: 'concent-string',
@@ -66,7 +64,7 @@ describe('Yandex adapter', function () {
const bidderRequest = {
refererInfo: {
- referer: refererUrl
+ domain: 'yandex.ru'
},
gdprConsent
};
diff --git a/test/spec/modules/yieldlabBidAdapter_spec.js b/test/spec/modules/yieldlabBidAdapter_spec.js
index e4d258ecdea..4c39fe5fe29 100644
--- a/test/spec/modules/yieldlabBidAdapter_spec.js
+++ b/test/spec/modules/yieldlabBidAdapter_spec.js
@@ -3,79 +3,80 @@ import { expect } from 'chai'
import { spec } from 'modules/yieldlabBidAdapter.js'
import { newBidder } from 'src/adapters/bidderFactory.js'
-const REQUEST = {
- 'bidder': 'yieldlab',
- 'params': {
- 'adslotId': '1111',
- 'supplyId': '2222',
- 'targeting': {
- 'key1': 'value1',
- 'key2': 'value2',
- 'notDoubleEncoded': 'value3,value4'
+const DEFAULT_REQUEST = () => ({
+ bidder: 'yieldlab',
+ params: {
+ adslotId: '1111',
+ supplyId: '2222',
+ targeting: {
+ key1: 'value1',
+ key2: 'value2',
+ notDoubleEncoded: 'value3,value4'
},
- 'customParams': {
- 'extraParam': true,
- 'foo': 'bar'
+ customParams: {
+ extraParam: true,
+ foo: 'bar'
},
- 'extId': 'abc',
- 'iabContent': {
- 'id': 'foo_id',
- 'episode': '99',
- 'title': 'foo_title,bar_title',
- 'series': 'foo_series',
- 'season': 's1',
- 'artist': 'foo bar',
- 'genre': 'baz',
- 'isrc': 'CC-XXX-YY-NNNNN',
- 'url': 'http://foo_url.de',
- 'cat': ['cat1', 'cat2,ppp', 'cat3|||//'],
- 'context': '7',
- 'keywords': ['k1,', 'k2..'],
- 'live': '0'
+ extId: 'abc',
+ iabContent: {
+ id: 'foo_id',
+ episode: '99',
+ title: 'foo_title,bar_title',
+ series: 'foo_series',
+ season: 's1',
+ artist: 'foo bar',
+ genre: 'baz',
+ isrc: 'CC-XXX-YY-NNNNN',
+ url: 'http://foo_url.de',
+ cat: ['cat1', 'cat2,ppp', 'cat3|||//'],
+ context: '7',
+ keywords: ['k1,', 'k2..'],
+ live: '0'
}
},
- 'bidderRequestId': '143346cf0f1731',
- 'auctionId': '2e41f65424c87c',
- 'adUnitCode': 'adunit-code',
- 'bidId': '2d925f27f5079f',
- 'sizes': [728, 90],
- 'userIdAsEids': [{
- 'source': 'netid.de',
- 'uids': [{
- 'id': 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg',
- 'atype': 1
+ bidderRequestId: '143346cf0f1731',
+ auctionId: '2e41f65424c87c',
+ adUnitCode: 'adunit-code',
+ bidId: '2d925f27f5079f',
+ sizes: [728, 90],
+ userIdAsEids: [{
+ source: 'netid.de',
+ uids: [{
+ id: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg',
+ atype: 1
}]
}],
- 'schain': {
- 'ver': '1.0',
- 'complete': 1,
- 'nodes': [
+ schain: {
+ ver: '1.0',
+ complete: 1,
+ nodes: [
{
- 'asi': 'indirectseller.com',
- 'sid': '1',
- 'hp': 1
+ asi: 'indirectseller.com',
+ sid: '1',
+ hp: 1
},
{
- 'asi': 'indirectseller2.com',
- 'name': 'indirectseller2 name with comma , and bang !',
- 'sid': '2',
- 'hp': 1
+ asi: 'indirectseller2.com',
+ name: 'indirectseller2 name with comma , and bang !',
+ sid: '2',
+ hp: 1
}
]
}
-}
+})
-const VIDEO_REQUEST = Object.assign({}, REQUEST, {
- 'mediaTypes': {
- 'video': {
- 'context': 'instream'
+const VIDEO_REQUEST = () => Object.assign(DEFAULT_REQUEST(), {
+ mediaTypes: {
+ video: {
+ playerSize: [[640, 480]],
+ context: 'instream'
}
}
})
-const NATIVE_REQUEST = Object.assign({}, REQUEST, {
- 'mediaTypes': {
- 'native': { }
+const NATIVE_REQUEST = () => Object.assign(DEFAULT_REQUEST(), {
+ mediaTypes: {
+ native: {}
}
})
@@ -91,34 +92,34 @@ const RESPONSE = {
}
const NATIVE_RESPONSE = Object.assign({}, RESPONSE, {
- 'adtype': 'NATIVE',
- 'native': {
- 'link': {
- 'url': 'https://www.yieldlab.de'
+ adtype: 'NATIVE',
+ native: {
+ link: {
+ url: 'https://www.yieldlab.de'
},
- 'assets': [
+ assets: [
{
- 'id': 1,
- 'title': {
- 'text': 'This is a great headline'
+ id: 1,
+ title: {
+ text: 'This is a great headline'
}
},
{
- 'id': 2,
- 'img': {
- 'url': 'https://localhost:8080/yl-logo100x100.jpg',
- 'w': 100,
- 'h': 100
+ id: 2,
+ img: {
+ url: 'https://localhost:8080/yl-logo100x100.jpg',
+ w: 100,
+ h: 100
}
},
{
- 'id': 3,
- 'data': {
- 'value': 'Native body value'
+ id: 3,
+ data: {
+ value: 'Native body value'
}
}
],
- 'imptrackers': [
+ imptrackers: [
'http://localhost:8080/ve?d=ODE9ZSY2MTI1MjAzNjMzMzYxPXN0JjA0NWUwZDk0NTY5Yi05M2FiLWUwZTQtOWFjNy1hYWY0MzFiZj1kaXQmMj12',
'http://localhost:8080/md/1111/9efa4e76-2030-4f04-bb9f-322541f8d611?mdata=false&pvid=false&ids=x:1',
'http://localhost:8080/imp?s=13216&d=2171514&a=12548955&ts=1633363025216&tid=fb134faa-7ca9-4e0e-ba39-b96549d0e540&l=0'
@@ -127,11 +128,11 @@ const NATIVE_RESPONSE = Object.assign({}, RESPONSE, {
})
const VIDEO_RESPONSE = Object.assign({}, RESPONSE, {
- 'adtype': 'VIDEO'
+ adtype: 'VIDEO'
})
const PVID_RESPONSE = Object.assign({}, VIDEO_RESPONSE, {
- 'pvid': '43513f11-55a0-4a83-94e5-0ebc08f54a2c'
+ pvid: '43513f11-55a0-4a83-94e5-0ebc08f54a2c'
})
const REQPARAMS = {
@@ -148,134 +149,214 @@ const REQPARAMS_IAB_CONTENT = Object.assign({}, REQPARAMS, {
iab_content: 'id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0'
})
-describe('yieldlabBidAdapter', function () {
- const adapter = newBidder(spec)
-
- describe('inherited functions', function () {
- it('exists and is a function', function () {
- expect(adapter.callBids).to.exist.and.to.be.a('function')
+describe('yieldlabBidAdapter', () => {
+ describe('instantiation from spec', () => {
+ it('is working properly', () => {
+ const yieldlabBidAdapter = newBidder(spec)
+ expect(yieldlabBidAdapter.callBids).to.exist.and.to.be.a('function')
})
})
- describe('isBidRequestValid', function () {
- it('should return true when required params found', function () {
+ describe('isBidRequestValid', () => {
+ it('should return true when all required parameters are found', () => {
const request = {
- 'params': {
- 'adslotId': '1111',
- 'supplyId': '2222'
+ params: {
+ adslotId: '1111',
+ supplyId: '2222'
}
}
expect(spec.isBidRequestValid(request)).to.equal(true)
})
- it('should return false when required params are not passed', function () {
+ it('should return false when required parameters are missing', () => {
expect(spec.isBidRequestValid({})).to.equal(false)
})
})
- describe('buildRequests', function () {
- const bidRequests = [REQUEST]
- const request = spec.buildRequests(bidRequests)
+ describe('buildRequests', () => {
+ const bidRequests = [DEFAULT_REQUEST()]
- it('sends bid request to ENDPOINT via GET', function () {
- expect(request.method).to.equal('GET')
- })
+ describe('default functionality', () => {
+ let request
- it('returns a list of valid requests', function () {
- expect(request.validBidRequests).to.eql([REQUEST])
- })
+ before(() => {
+ request = spec.buildRequests(bidRequests)
+ })
- it('passes single-encoded targeting to bid request', function () {
- expect(request.url).to.include('t=key1%3Dvalue1%26key2%3Dvalue2%26notDoubleEncoded%3Dvalue3%2Cvalue4')
- })
+ it('sends bid request to ENDPOINT via GET', () => {
+ expect(request.method).to.equal('GET')
+ })
- it('passes userids to bid request', function () {
- expect(request.url).to.include('ids=netid.de%3AfH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg')
- })
+ it('returns a list of valid requests', () => {
+ expect(request.validBidRequests).to.eql(bidRequests)
+ })
- it('passes extra params to bid request', function () {
- expect(request.url).to.include('extraParam=true&foo=bar')
- })
+ it('passes single-encoded targeting to bid request', () => {
+ expect(request.url).to.include('t=key1%3Dvalue1%26key2%3Dvalue2%26notDoubleEncoded%3Dvalue3%2Cvalue4')
+ })
- it('passes unencoded schain string to bid request', function () {
- expect(request.url).to.include('schain=1.0,1!indirectseller.com,1,1,,,,!indirectseller2.com,2,1,,indirectseller2%20name%20with%20comma%20%2C%20and%20bang%20%21,,')
- })
+ it('passes userids to bid request', () => {
+ expect(request.url).to.include('ids=netid.de%3AfH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg')
+ })
+
+ it('passes extra params to bid request', () => {
+ expect(request.url).to.include('extraParam=true&foo=bar')
+ })
+
+ it('passes unencoded schain string to bid request', () => {
+ expect(request.url).to.include('schain=1.0,1!indirectseller.com,1,1,,,,!indirectseller2.com,2,1,,indirectseller2%20name%20with%20comma%20%2C%20and%20bang%20%21,,')
+ })
+
+ it('passes iab_content string to bid request', () => {
+ expect(request.url).to.include('iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
+ })
- it('passes iab_content string to bid request', function () {
- expect(request.url).to.include('iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
+ it('passes correct size to bid request', () => {
+ expect(request.url).to.include('728x90')
+ })
+
+ it('passes external id to bid request', () => {
+ expect(request.url).to.include('id=abc')
+ })
})
- const siteConfig = {
- 'ortb2': {
- 'site': {
- 'content': {
- 'id': 'id_from_config'
+ describe('iab_content handling', () => {
+ const siteConfig = {
+ ortb2: {
+ site: {
+ content: {
+ id: 'id_from_config'
+ }
}
}
}
- }
- it('generates iab_content string from bidder params', function () {
- config.setConfig(siteConfig);
- const request = spec.buildRequests([REQUEST])
- expect(request.url).to.include('iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
- config.resetConfig();
- })
+ beforeEach(() => {
+ config.setConfig(siteConfig)
+ })
- it('generates iab_content string from first party data if not provided in bidder params', function () {
- const requestWithoutIabContent = {
- 'params': {
- 'adslotId': '1111',
- 'supplyId': '2222'
- }
- }
- config.setConfig(siteConfig);
- const request = spec.buildRequests([requestWithoutIabContent])
- expect(request.url).to.include('iab_content=id%3Aid_from_config')
- config.resetConfig();
- })
+ afterEach(() => {
+ config.resetConfig()
+ })
- const refererRequest = spec.buildRequests(bidRequests, {
- refererInfo: {
- canonicalUrl: undefined,
- numIframes: 0,
- reachedTop: true,
- referer: 'https://www.yieldlab.de/test?with=querystring',
- stack: ['https://www.yieldlab.de/test?with=querystring']
- }
+ it('generates iab_content string from bidder params', () => {
+ const request = spec.buildRequests(bidRequests)
+ expect(request.url).to.include('iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
+ })
+
+ it('generates iab_content string from first party data if not provided in bidder params', () => {
+ const requestWithoutIabContent = DEFAULT_REQUEST()
+ delete requestWithoutIabContent.params.iabContent
+
+ const request = spec.buildRequests([{...requestWithoutIabContent, ...siteConfig}])
+ expect(request.url).to.include('iab_content=id%3Aid_from_config')
+ })
})
- it('passes unencoded schain string to bid request when complete == 0', function () {
- REQUEST.schain.complete = 0;
- const request = spec.buildRequests([REQUEST])
+ it('passes unencoded schain string to bid request when complete == 0', () => {
+ const schainRequest = DEFAULT_REQUEST()
+ schainRequest.schain.complete = 0; //
+ const request = spec.buildRequests([schainRequest])
expect(request.url).to.include('schain=1.0,0!indirectseller.com,1,1,,,,!indirectseller2.com,2,1,,indirectseller2%20name%20with%20comma%20%2C%20and%20bang%20%21,,')
})
- it('passes encoded referer to bid request', function () {
+ it('passes encoded referer to bid request', () => {
+ const refererRequest = spec.buildRequests(bidRequests, {
+ refererInfo: {
+ canonicalUrl: undefined,
+ numIframes: 0,
+ reachedTop: true,
+ page: 'https://www.yieldlab.de/test?with=querystring',
+ stack: ['https://www.yieldlab.de/test?with=querystring']
+ }
+ })
+
expect(refererRequest.url).to.include('pubref=https%3A%2F%2Fwww.yieldlab.de%2Ftest%3Fwith%3Dquerystring')
})
- const gdprRequest = spec.buildRequests(bidRequests, {
- gdprConsent: {
- consentString: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA',
- gdprApplies: true
- }
- })
+ it('passes gdpr flag and consent if present', () => {
+ const gdprRequest = spec.buildRequests(bidRequests, {
+ gdprConsent: {
+ consentString: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA',
+ gdprApplies: true
+ }
+ })
- it('passes gdpr flag and consent if present', function () {
expect(gdprRequest.url).to.include('consent=BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA')
expect(gdprRequest.url).to.include('gdpr=true')
})
+
+ describe('sizes handling', () => {
+ it('passes correct size to bid request for mediaType banner', () => {
+ const bannerRequest = DEFAULT_REQUEST();
+ bannerRequest.mediaTypes = {
+ banner: {
+ sizes: [[123, 456]]
+ }
+ }
+
+ // when mediaTypes is present it has precedence over the sizes field (728, 90)
+ let request = spec.buildRequests([bannerRequest], REQPARAMS)
+ expect(request.url).to.include('sizes')
+ expect(request.url).to.include('123x456')
+
+ bannerRequest.mediaTypes.banner.sizes = [123, 456]
+ request = spec.buildRequests([bannerRequest], REQPARAMS)
+ expect(request.url).to.include('123x456')
+
+ bannerRequest.mediaTypes.banner.sizes = [[123, 456], [320, 240]]
+ request = spec.buildRequests([bannerRequest], REQPARAMS)
+ expect(request.url).to.include('123x456')
+ expect(request.url).to.include('320x240')
+ })
+
+ it('passes correct sizes to bid request when mediaType is not present', () => {
+ // information is taken from the top level sizes field
+ const sizesRequest = DEFAULT_REQUEST();
+
+ let request = spec.buildRequests([sizesRequest], REQPARAMS)
+ expect(request.url).to.include('sizes')
+ expect(request.url).to.include('728x90')
+
+ sizesRequest.sizes = [[728, 90]]
+ request = spec.buildRequests([sizesRequest], REQPARAMS)
+ expect(request.url).to.include('728x90')
+
+ sizesRequest.sizes = [[728, 90], [320, 240]]
+ request = spec.buildRequests([sizesRequest], REQPARAMS)
+ expect(request.url).to.include('728x90')
+ })
+
+ it('does not pass the sizes parameter for mediaType video', () => {
+ const videoRequest = VIDEO_REQUEST();
+
+ let request = spec.buildRequests([videoRequest], REQPARAMS)
+ expect(request.url).to.not.include('sizes')
+ })
+
+ it('does not pass the sizes parameter for mediaType native', () => {
+ const nativeRequest = NATIVE_REQUEST();
+
+ let request = spec.buildRequests([nativeRequest], REQPARAMS)
+ expect(request.url).to.not.include('sizes')
+ })
+ })
})
- describe('interpretResponse', function () {
- it('handles nobid responses', function () {
+ describe('interpretResponse', () => {
+ let bidRequest
+
+ before(() => {
+ bidRequest = DEFAULT_REQUEST()
+ })
+
+ it('handles nobid responses', () => {
expect(spec.interpretResponse({body: {}}, {validBidRequests: []}).length).to.equal(0)
expect(spec.interpretResponse({body: []}, {validBidRequests: []}).length).to.equal(0)
})
- it('should get correct bid response', function () {
- const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [REQUEST], queryParams: REQPARAMS})
+ it('should get correct bid response', () => {
+ const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [bidRequest], queryParams: REQPARAMS})
expect(result[0].requestId).to.equal('2d925f27f5079f')
expect(result[0].cpm).to.equal(0.01)
@@ -292,21 +373,21 @@ describe('yieldlabBidAdapter', function () {
expect(result[0].ad).to.include('&id=abc')
})
- it('should append gdpr parameters to adtag', function () {
- const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [REQUEST], queryParams: REQPARAMS_GDPR})
+ it('should append gdpr parameters to adtag', () => {
+ const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [bidRequest], queryParams: REQPARAMS_GDPR})
expect(result[0].ad).to.include('&gdpr=true')
expect(result[0].ad).to.include('&consent=BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA')
})
- it('should append iab_content to adtag', function () {
- const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [REQUEST], queryParams: REQPARAMS_IAB_CONTENT})
+ it('should append iab_content to adtag', () => {
+ const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [bidRequest], queryParams: REQPARAMS_IAB_CONTENT})
expect(result[0].ad).to.include('&iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
})
- it('should get correct bid response when passing more than one size', function () {
- const REQUEST2 = Object.assign({}, REQUEST, {
- 'sizes': [
+ it('should get correct bid response when passing more than one size', () => {
+ const REQUEST2 = Object.assign(DEFAULT_REQUEST(), {
+ sizes: [
[800, 250],
[728, 90],
[970, 90],
@@ -329,8 +410,8 @@ describe('yieldlabBidAdapter', function () {
expect(result[0].ad).to.include('&id=abc')
})
- it('should add vastUrl when type is video', function () {
- const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST], queryParams: REQPARAMS})
+ it('should add vastUrl when type is video', () => {
+ const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST()], queryParams: REQPARAMS})
expect(result[0].requestId).to.equal('2d925f27f5079f')
expect(result[0].cpm).to.equal(0.01)
@@ -339,8 +420,8 @@ describe('yieldlabBidAdapter', function () {
expect(result[0].vastUrl).to.include('&id=abc')
})
- it('should add adUrl and native assets when type is Native', function () {
- const result = spec.interpretResponse({body: [NATIVE_RESPONSE]}, {validBidRequests: [NATIVE_REQUEST], queryParams: REQPARAMS})
+ it('should add adUrl and native assets when type is Native', () => {
+ const result = spec.interpretResponse({body: [NATIVE_RESPONSE]}, {validBidRequests: [NATIVE_REQUEST()], queryParams: REQPARAMS})
expect(result[0].requestId).to.equal('2d925f27f5079f')
expect(result[0].cpm).to.equal(0.01)
@@ -355,17 +436,17 @@ describe('yieldlabBidAdapter', function () {
expect(result[0].native.impressionTrackers.length).to.equal(3)
})
- it('should add adUrl and default native assets when type is Native', function () {
+ it('should add adUrl and default native assets when type is Native', () => {
const NATIVE_RESPONSE_2 = Object.assign({}, NATIVE_RESPONSE, {
- 'native': {
- 'link': {
- 'url': 'https://www.yieldlab.de'
+ native: {
+ link: {
+ url: 'https://www.yieldlab.de'
},
- 'assets': [],
- 'imptrackers': []
+ assets: [],
+ imptrackers: []
}
})
- const result = spec.interpretResponse({body: [NATIVE_RESPONSE_2]}, {validBidRequests: [NATIVE_REQUEST], queryParams: REQPARAMS})
+ const result = spec.interpretResponse({body: [NATIVE_RESPONSE_2]}, {validBidRequests: [NATIVE_REQUEST()], queryParams: REQPARAMS})
expect(result[0].requestId).to.equal('2d925f27f5079f')
expect(result[0].cpm).to.equal(0.01)
@@ -378,19 +459,19 @@ describe('yieldlabBidAdapter', function () {
expect(result[0].native.image.height).to.equal(0)
})
- it('should append gdpr parameters to vastUrl', function () {
- const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST], queryParams: REQPARAMS_GDPR})
+ it('should append gdpr parameters to vastUrl', () => {
+ const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST()], queryParams: REQPARAMS_GDPR})
expect(result[0].vastUrl).to.include('&gdpr=true')
expect(result[0].vastUrl).to.include('&consent=BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA')
})
- it('should add renderer if outstream context', function () {
- const OUTSTREAM_REQUEST = Object.assign({}, REQUEST, {
- 'mediaTypes': {
- 'video': {
- 'playerSize': [[640, 480]],
- 'context': 'outstream'
+ it('should add renderer if outstream context', () => {
+ const OUTSTREAM_REQUEST = Object.assign(DEFAULT_REQUEST(), {
+ mediaTypes: {
+ video: {
+ playerSize: [[640, 480]],
+ context: 'outstream'
}
}
})
@@ -402,27 +483,27 @@ describe('yieldlabBidAdapter', function () {
expect(result[0].height).to.equal(480)
})
- it('should add pvid to adtag urls when present', function () {
- const result = spec.interpretResponse({body: [PVID_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST], queryParams: REQPARAMS})
+ it('should add pvid to adtag urls when present', () => {
+ const result = spec.interpretResponse({body: [PVID_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST()], queryParams: REQPARAMS})
expect(result[0].ad).to.include('&pvid=43513f11-55a0-4a83-94e5-0ebc08f54a2c')
expect(result[0].vastUrl).to.include('&pvid=43513f11-55a0-4a83-94e5-0ebc08f54a2c')
})
- it('should append iab_content to vastUrl', function () {
- const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST], queryParams: REQPARAMS_IAB_CONTENT})
+ it('should append iab_content to vastUrl', () => {
+ const result = spec.interpretResponse({body: [VIDEO_RESPONSE]}, {validBidRequests: [VIDEO_REQUEST()], queryParams: REQPARAMS_IAB_CONTENT})
expect(result[0].vastUrl).to.include('&iab_content=id%3Afoo_id%2Cepisode%3A99%2Ctitle%3Afoo_title%252Cbar_title%2Cseries%3Afoo_series%2Cseason%3As1%2Cartist%3Afoo%2520bar%2Cgenre%3Abaz%2Cisrc%3ACC-XXX-YY-NNNNN%2Curl%3Ahttp%253A%252F%252Ffoo_url.de%2Ccat%3Acat1%7Ccat2%252Cppp%7Ccat3%257C%257C%257C%252F%252F%2Ccontext%3A7%2Ckeywords%3Ak1%252C%7Ck2..%2Clive%3A0')
})
})
- describe('getUserSyncs', function () {
+ describe('getUserSyncs', () => {
const syncOptions = {
iframeEnabled: true,
pixelEnabled: false
};
const expectedUrlSnippets = ['https://ad.yieldlab.net/d/6846326/766/2x2?', 'ts=', 'type=h'];
- it('should return user sync as expected', function () {
+ it('should return user sync as expected', () => {
const bidRequest = {
gdprConsent: {
consentString: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA',
@@ -439,7 +520,7 @@ describe('yieldlabBidAdapter', function () {
expect(sync[0].type).to.have.string('iframe');
});
- it('should return user sync even without gdprApplies in gdprConsent', function () {
+ it('should return user sync even without gdprApplies in gdprConsent', () => {
const gdprConsent = {
consentString: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA'
}
@@ -450,4 +531,41 @@ describe('yieldlabBidAdapter', function () {
expect(sync[0].type).to.have.string('iframe');
});
});
+
+ describe('getBidFloor', function () {
+ let bidRequest, getFloor;
+
+ it('should add valid bid floor', () => {
+ getFloor = () => {
+ return {
+ currency: 'EUR',
+ floor: 1.33
+ };
+ };
+ bidRequest = Object.assign(DEFAULT_REQUEST(), {getFloor})
+ const result = spec.buildRequests([bidRequest], REQPARAMS)
+ expect(result).to.have.nested.property('queryParams.floor', 1.33)
+ });
+
+ it('should not add empty bid floor', () => {
+ getFloor = () => {
+ return {};
+ };
+ bidRequest = Object.assign(DEFAULT_REQUEST(), {getFloor})
+ const result = spec.buildRequests([bidRequest], REQPARAMS)
+ expect(result).not.to.have.nested.property('queryParams.floor')
+ });
+
+ it('should not add bid floor when currency is not matching', () => {
+ getFloor = (currency, mediaType, size) => {
+ return {
+ currency: 'USD',
+ floor: 1.33
+ };
+ };
+ bidRequest = Object.assign(DEFAULT_REQUEST(), {getFloor})
+ const result = spec.buildRequests([bidRequest], REQPARAMS)
+ expect(result).not.to.have.nested.property('queryParams.floor')
+ });
+ });
})
diff --git a/test/spec/modules/yieldliftBidAdapter_spec.js b/test/spec/modules/yieldliftBidAdapter_spec.js
index 86a7b83e2c6..c2379ed7778 100644
--- a/test/spec/modules/yieldliftBidAdapter_spec.js
+++ b/test/spec/modules/yieldliftBidAdapter_spec.js
@@ -45,7 +45,7 @@ const RESPONSE = {
'price': 0.18,
'adm': '',
'adid': '144762342',
- 'adomain': [
+ 'advertiserDomains': [
'https://dummydomain.com'
],
'iurl': 'iurl',
@@ -74,7 +74,7 @@ const RESPONSE = {
'price': 0.1,
'adm': '',
'adid': '144762342',
- 'adomain': [
+ 'advertiserDomains': [
'https://dummydomain.com'
],
'iurl': 'iurl',
@@ -191,6 +191,26 @@ describe('YieldLift', function () {
expect(payload.user.ext).to.have.property('consent', req.gdprConsent.consentString);
expect(payload.regs.ext).to.have.property('gdpr', 1);
});
+
+ it('should properly forward eids parameters', function () {
+ const req = Object.assign({}, REQUEST);
+ req.bidRequest[0].userIdAsEids = [
+ {
+ source: 'dummy.com',
+ uids: [
+ {
+ id: 'd6d0a86c-20c6-4410-a47b-5cba383a698a',
+ atype: 1
+ }
+ ]
+ }];
+ let request = spec.buildRequests(req.bidRequest, req);
+
+ const payload = JSON.parse(request.data);
+ expect(payload.user.ext.eids[0].source).to.equal('dummy.com');
+ expect(payload.user.ext.eids[0].uids[0].id).to.equal('d6d0a86c-20c6-4410-a47b-5cba383a698a');
+ expect(payload.user.ext.eids[0].uids[0].atype).to.equal(1);
+ });
});
describe('interpretResponse', function () {
@@ -208,7 +228,7 @@ describe('YieldLift', function () {
expect(bids[index]).to.have.property('height', RESPONSE.body.seatbid[0].bid[index].h);
expect(bids[index]).to.have.property('ad', RESPONSE.body.seatbid[0].bid[index].adm);
expect(bids[index]).to.have.property('creativeId', RESPONSE.body.seatbid[0].bid[index].crid);
- expect(bids[index].meta).to.have.property('adomain', RESPONSE.body.seatbid[0].bid[index].adomain);
+ expect(bids[index].meta).to.have.property('advertiserDomains', RESPONSE.body.seatbid[0].bid[index].advertiserDomains);
expect(bids[index]).to.have.property('ttl', 30);
expect(bids[index]).to.have.property('netRevenue', true);
}
diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js
index f72705a79ac..32f0ead11f1 100644
--- a/test/spec/modules/yieldmoBidAdapter_spec.js
+++ b/test/spec/modules/yieldmoBidAdapter_spec.js
@@ -2,9 +2,13 @@ import { expect } from 'chai';
import { spec } from 'modules/yieldmoBidAdapter.js';
import * as utils from 'src/utils.js';
+/* eslint no-console: ["error", { allow: ["log", "warn", "error"] }] */
+// above is used for debugging purposes only
+
describe('YieldmoAdapter', function () {
const BANNER_ENDPOINT = 'https://ads.yieldmo.com/exchange/prebid';
const VIDEO_ENDPOINT = 'https://ads.yieldmo.com/exchange/prebidvideo';
+ const PB_COOKIE_ASSIST_SYNC_ENDPOINT = `https://ads.yieldmo.com/pbcas`;
const mockBannerBid = (rootParams = {}, params = {}) => ({
bidder: 'yieldmo',
@@ -37,6 +41,7 @@ describe('YieldmoAdapter', function () {
bidder: 'yieldmo',
adUnitCode: 'adunit-code-video',
bidId: '321video123',
+ auctionId: '1d1a03073455',
mediaTypes: {
video: {
playerSize: [640, 480],
@@ -171,15 +176,15 @@ describe('YieldmoAdapter', function () {
it('should place bid information into the p parameter of data', function () {
let bidArray = [mockBannerBid()];
expect(buildAndGetPlacementInfo(bidArray)).to.equal(
- '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]'
+ '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1,"auctionId":"1d1a030790a475"}]'
);
// multiple placements
bidArray.push(mockBannerBid(
{adUnitCode: 'adunit-2', bidId: '123a', bidderRequestId: '321', auctionId: '222'}, {bidFloor: 0.2}));
expect(buildAndGetPlacementInfo(bidArray)).to.equal(
- '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},' +
- '{"placement_id":"adunit-2","callback_id":"123a","sizes":[[300,250],[300,600]],"bidFloor":0.2}]'
+ '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1,"auctionId":"1d1a030790a475"},' +
+ '{"placement_id":"adunit-2","callback_id":"123a","sizes":[[300,250],[300,600]],"bidFloor":0.2,"auctionId":"222"}]'
);
});
@@ -217,6 +222,24 @@ describe('YieldmoAdapter', function () {
expect(buildAndGetData([pubcidBid]).pubcid).to.deep.equal(pubcid);
});
+ it('should add transaction id as parameter of request', function () {
+ const transactionId = '54a58774-7a41-494e-9aaf-fa7b79164f0c';
+ const pubcidBid = mockBannerBid({ ortb2Imp: {
+ ext: {
+ tid: '54a58774-7a41-494e-9aaf-fa7b79164f0c',
+ }
+ }});
+ const bidRequest = buildAndGetData([pubcidBid]);
+ expect(bidRequest.p).to.contain(transactionId);
+ });
+
+ it('should add auction id as parameter of request', function () {
+ const auctionId = '1d1a030790a475';
+ const pubcidBid = mockBannerBid({});
+ const bidRequest = buildAndGetData([pubcidBid]);
+ expect(bidRequest.p).to.contain(auctionId);
+ });
+
it('should add unified id as parameter of request', function () {
const unifiedIdBid = mockBannerBid({crumbs: undefined});
expect(buildAndGetData([unifiedIdBid]).tdid).to.deep.equal(mockBannerBid().userId.tdid);
@@ -470,6 +493,24 @@ describe('YieldmoAdapter', function () {
expect(requests[0].data.ats_envelope).to.equal(envelope);
});
+ it('should add transaction id to video bid request', function() {
+ const transactionId = '54a58774-7a41-494e-8cbc-fa7b79164f0c';
+ const requestData = {
+ ortb2Imp: {
+ ext: {
+ tid: '54a58774-7a41-494e-8cbc-fa7b79164f0c',
+ }
+ }
+ };
+ expect(buildAndGetData([mockVideoBid({...requestData})]).imp[0].ext.tid).to.equal(transactionId);
+ });
+
+ it('should add auction id to video bid request', function() {
+ const auctionId = '1d1a03073455';
+
+ expect(buildAndGetData([mockVideoBid({})]).auctionId).to.deep.equal(auctionId);
+ });
+
it('should add schain if it is in the bidRequest', () => {
const schain = {
ver: '1.0',
@@ -606,8 +647,20 @@ describe('YieldmoAdapter', function () {
});
describe('getUserSync', function () {
- it('should return a tracker with type and url as parameters', function () {
- expect(spec.getUserSyncs()).to.deep.equal([]);
+ const gdprFlag = `&gdpr=0`;
+ const usPrivacy = `us_privacy=`;
+ const gdprString = `&gdpr_consent=`;
+ const pbCookieAssistSyncUrl = `${PB_COOKIE_ASSIST_SYNC_ENDPOINT}?${usPrivacy}${gdprFlag}${gdprString}`;
+ it('should use type iframe when iframeEnabled', function() {
+ const syncs = spec.getUserSyncs({iframeEnabled: true});
+ expect(syncs).to.deep.equal([{type: 'iframe', url: pbCookieAssistSyncUrl + '&type=iframe'}])
+ });
+ it('should use type image when pixelEnabled', function() {
+ const syncs = spec.getUserSyncs({pixelEnabled: true});
+ expect(syncs).to.deep.equal([{type: 'image', url: pbCookieAssistSyncUrl + '&type=image'}])
+ });
+ it('should register no syncs', function () {
+ expect(spec.getUserSyncs({})).to.deep.equal([]);
});
});
});
diff --git a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js
index 81a6365bba2..f55577913a5 100644
--- a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js
+++ b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js
@@ -46,7 +46,7 @@ describe('Yieldone Prebid Analytic', function () {
{
bidderCode: 'biddertest_1',
auctionId: auctionId,
- refererInfo: {referer: testReferrer},
+ refererInfo: {page: testReferrer},
bids: [
{
adUnitCode: '0000',
@@ -71,7 +71,7 @@ describe('Yieldone Prebid Analytic', function () {
{
bidderCode: 'biddertest_2',
auctionId: auctionId,
- refererInfo: {referer: testReferrer},
+ refererInfo: {page: testReferrer},
bids: [
{
adUnitCode: '0000',
@@ -87,7 +87,7 @@ describe('Yieldone Prebid Analytic', function () {
{
bidderCode: 'biddertest_3',
auctionId: auctionId,
- refererInfo: {referer: testReferrer},
+ refererInfo: {page: testReferrer},
bids: [
{
adUnitCode: '0000',
@@ -269,7 +269,11 @@ describe('Yieldone Prebid Analytic', function () {
setTimeout(function() {
events.emit(constants.EVENTS.BID_WON, winner);
- sinon.assert.callCount(sendStatStub, 2);
+ sinon.assert.callCount(sendStatStub, 2)
+ const billableEventIndex = yieldoneAnalytics.eventsStorage[auctionId].events.findIndex(event => event.eventType === constants.EVENTS.BILLABLE_EVENT);
+ if (billableEventIndex > -1) {
+ yieldoneAnalytics.eventsStorage[auctionId].events.splice(billableEventIndex, 1);
+ }
expect(yieldoneAnalytics.eventsStorage[auctionId]).to.deep.equal(wonExpectedResult);
delete yieldoneAnalytics.eventsStorage[auctionId];
diff --git a/test/spec/modules/yieldoneBidAdapter_spec.js b/test/spec/modules/yieldoneBidAdapter_spec.js
index d452d78e147..e41764b2876 100644
--- a/test/spec/modules/yieldoneBidAdapter_spec.js
+++ b/test/spec/modules/yieldoneBidAdapter_spec.js
@@ -399,6 +399,76 @@ describe('yieldoneBidAdapter', function() {
expect(request[0].data.imuid).to.equal('imuid_sample');
});
});
+
+ describe('DAC ID', function () {
+ it('dont send DAC ID if undefined', function () {
+ const bidRequests = [
+ {
+ params: {placementId: '0'},
+ },
+ {
+ params: {placementId: '1'},
+ userId: {},
+ },
+ {
+ params: {placementId: '2'},
+ userId: undefined,
+ },
+ ];
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data).to.not.have.property('dac_id');
+ expect(request[1].data).to.not.have.property('dac_id');
+ expect(request[2].data).to.not.have.property('dac_id');
+ expect(request[0].data).to.not.have.property('fuuid');
+ expect(request[1].data).to.not.have.property('fuuid');
+ expect(request[2].data).to.not.have.property('fuuid');
+ });
+
+ it('should send DAC ID if available', function () {
+ const bidRequests = [
+ {
+ params: {placementId: '0'},
+ userId: {dacId: {id: 'dacId_sample'}},
+ },
+ ];
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.dac_id).to.equal('dacId_sample');
+ expect(request[0].data.fuuid).to.equal('dacId_sample');
+ });
+ });
+
+ describe('ID5', function () {
+ it('dont send ID5 if undefined', function () {
+ const bidRequests = [
+ {
+ params: {placementId: '0'},
+ },
+ {
+ params: {placementId: '1'},
+ userId: {},
+ },
+ {
+ params: {placementId: '2'},
+ userId: undefined,
+ },
+ ];
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data).to.not.have.property('id5Id');
+ expect(request[1].data).to.not.have.property('id5Id');
+ expect(request[2].data).to.not.have.property('id5Id');
+ });
+
+ it('should send ID5 if available', function () {
+ const bidRequests = [
+ {
+ params: {placementId: '0'},
+ userId: {id5id: {uid: 'id5id_sample'}},
+ },
+ ];
+ const request = spec.buildRequests(bidRequests, bidderRequest);
+ expect(request[0].data.id5Id).to.equal('id5id_sample');
+ });
+ });
});
describe('interpretResponse', function () {
@@ -413,7 +483,9 @@ describe('yieldoneBidAdapter', function() {
'cb': 12892917383,
'r': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836',
'uid': '23beaa6af6cdde',
- 't': 'i'
+ 't': 'i',
+ 'language': 'ja',
+ 'screen_size': '1440x900'
}
}
];
@@ -486,7 +558,9 @@ describe('yieldoneBidAdapter', function() {
'cb': 12892917383,
'r': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836',
'uid': '23beaa6af6cdde',
- 't': 'i'
+ 't': 'i',
+ 'language': 'ja',
+ 'screen_size': '1440x900'
}
}
];
diff --git a/test/spec/modules/zetaBidAdapter_spec.js b/test/spec/modules/zetaBidAdapter_spec.js
index 25350725dee..529fb8e8d31 100644
--- a/test/spec/modules/zetaBidAdapter_spec.js
+++ b/test/spec/modules/zetaBidAdapter_spec.js
@@ -10,7 +10,7 @@ describe('Zeta Bid Adapter', function() {
}
},
refererInfo: {
- referer: 'testprebid.com'
+ page: 'testprebid.com'
},
params: {
placement: 12345,
diff --git a/test/spec/modules/zeta_global_sspBidAdapter_spec.js b/test/spec/modules/zeta_global_sspBidAdapter_spec.js
index d439da8e711..3bd17697f2d 100644
--- a/test/spec/modules/zeta_global_sspBidAdapter_spec.js
+++ b/test/spec/modules/zeta_global_sspBidAdapter_spec.js
@@ -44,6 +44,48 @@ describe('Zeta Ssp Bid Adapter', function () {
test: 1
};
+ const multiImpRequest = [
+ {
+ bidId: 12345,
+ auctionId: 67890,
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250]],
+ }
+ },
+ refererInfo: {
+ page: 'http://www.zetaglobal.com/page?param=value',
+ domain: 'www.zetaglobal.com',
+ },
+ gdprConsent: {
+ gdprApplies: 1,
+ consentString: 'consentString'
+ },
+ uspConsent: 'someCCPAString',
+ params: params,
+ userIdAsEids: eids
+ }, {
+ bidId: 54321,
+ auctionId: 67890,
+ mediaTypes: {
+ banner: {
+ sizes: [[600, 400]],
+ }
+ },
+ refererInfo: {
+ page: 'http://www.zetaglobal.com/page?param=value',
+ domain: 'www.zetaglobal.com',
+ },
+ gdprConsent: {
+ gdprApplies: 1,
+ consentString: 'consentString'
+ },
+ uspConsent: 'someCCPAString',
+ params: params,
+ userIdAsEids: eids
+ }
+ ];
+
const bannerRequest = [{
bidId: 12345,
auctionId: 67890,
@@ -53,7 +95,8 @@ describe('Zeta Ssp Bid Adapter', function () {
}
},
refererInfo: {
- referer: 'http://www.zetaglobal.com/page?param=value'
+ page: 'http://www.zetaglobal.com/page?param=value',
+ domain: 'www.zetaglobal.com',
},
gdprConsent: {
gdprApplies: 1,
@@ -108,7 +151,7 @@ describe('Zeta Ssp Bid Adapter', function () {
const request = spec.buildRequests(bannerRequest, bannerRequest[0]);
const payload = JSON.parse(request.data);
expect(payload.site.page).to.eql('http://www.zetaglobal.com/page?param=value');
- expect(payload.site.domain).to.eql(window.location.origin); // config.js -> DEFAULT_PUBLISHER_DOMAIN
+ expect(payload.site.domain).to.eql('zetaglobal.com');
});
it('Test the request processing function', function () {
@@ -270,7 +313,7 @@ describe('Zeta Ssp Bid Adapter', function () {
it('Test required params in banner request', function () {
const request = spec.buildRequests(bannerRequest, bannerRequest[0]);
const payload = JSON.parse(request.data);
- expect(request.url).to.eql('https://ssp.disqus.com/bid?shortname=test_shortname');
+ expect(request.url).to.eql('https://ssp.disqus.com/bid/prebid?shortname=test_shortname');
expect(payload.ext.sid).to.eql('publisherId');
expect(payload.ext.tags.someTag).to.eql(444);
expect(payload.ext.tags.shortname).to.be.undefined;
@@ -279,9 +322,26 @@ describe('Zeta Ssp Bid Adapter', function () {
it('Test required params in video request', function () {
const request = spec.buildRequests(videoRequest, videoRequest[0]);
const payload = JSON.parse(request.data);
- expect(request.url).to.eql('https://ssp.disqus.com/bid?shortname=test_shortname');
+ expect(request.url).to.eql('https://ssp.disqus.com/bid/prebid?shortname=test_shortname');
expect(payload.ext.sid).to.eql('publisherId');
expect(payload.ext.tags.someTag).to.eql(444);
expect(payload.ext.tags.shortname).to.be.undefined;
});
+
+ it('Test multi imp', function () {
+ const request = spec.buildRequests(multiImpRequest, multiImpRequest[0]);
+ const payload = JSON.parse(request.data);
+ expect(request.url).to.eql('https://ssp.disqus.com/bid/prebid?shortname=test_shortname');
+
+ expect(payload.imp.length).to.eql(2);
+
+ expect(payload.imp[0].id).to.eql(12345);
+ expect(payload.imp[1].id).to.eql(54321);
+
+ expect(payload.imp[0].banner.w).to.eql(300);
+ expect(payload.imp[0].banner.h).to.eql(250);
+
+ expect(payload.imp[1].banner.w).to.eql(600);
+ expect(payload.imp[1].banner.h).to.eql(400);
+ });
});
diff --git a/test/spec/native_spec.js b/test/spec/native_spec.js
index 66e11b9a472..72eee1be85d 100644
--- a/test/spec/native_spec.js
+++ b/test/spec/native_spec.js
@@ -5,10 +5,14 @@ import {
nativeBidIsValid,
getAssetMessage,
getAllAssetsMessage,
- decorateAdUnitsWithNativeParams
+ decorateAdUnitsWithNativeParams,
+ isOpenRTBBidRequestValid,
+ isNativeOpenRTBBidValid,
+ toOrtbNativeRequest, toOrtbNativeResponse, legacyPropertiesToOrtbNative, fireImpressionTrackers, fireClickTrackers,
} from 'src/native.js';
import CONSTANTS from 'src/constants.json';
-import {stubAuctionIndex} from '../helpers/indexStub.js';
+import { stubAuctionIndex } from '../helpers/indexStub.js';
+import { convertOrtbRequestToProprietaryNative, fromOrtbNativeRequest } from '../../src/native.js';
const utils = require('src/utils');
const bid = {
@@ -21,25 +25,125 @@ const bid = {
image: {
url: 'http://cdn.example.com/p/creative-image/image.png',
height: 83,
- width: 127
+ width: 127,
},
icon: {
url: 'http://cdn.example.com/p/creative-image/icon.jpg',
height: 742,
- width: 989
+ width: 989,
},
sponsoredBy: 'AppNexus',
clickUrl: 'https://www.link.example',
clickTrackers: ['https://tracker.example'],
impressionTrackers: ['https://impression.example'],
- javascriptTrackers: '',
+ javascriptTrackers: '',
ext: {
foo: 'foo-value',
- baz: 'baz-value'
+ baz: 'baz-value',
+ },
+ },
+};
+
+const ortbBid = {
+ adId: '123',
+ transactionId: 'au',
+ native: {
+ ortb: {
+ assets: [
+ {
+ id: 0,
+ title: {
+ text: 'Native Creative'
+ }
+ },
+ {
+ id: 1,
+ data: {
+ value: 'Cool description great stuff'
+ }
+ },
+ {
+ id: 2,
+ data: {
+ value: 'Do it'
+ }
+ },
+ {
+ id: 3,
+ img: {
+ url: 'http://cdn.example.com/p/creative-image/image.png',
+ h: 83,
+ w: 127
+ }
+ },
+ {
+ id: 4,
+ img: {
+ url: 'http://cdn.example.com/p/creative-image/icon.jpg',
+ h: 742,
+ w: 989
+ }
+ },
+ {
+ id: 5,
+ data: {
+ value: 'AppNexus',
+ type: 1
+ }
+ }
+ ],
+ link: {
+ url: 'https://www.link.example'
+ },
+ privacy: 'https://privacy-link.example',
+ ver: '1.2'
}
- }
+ },
};
+const ortbRequest = {
+ assets: [
+ {
+ id: 0,
+ required: 0,
+ title: {
+ len: 140
+ }
+ }, {
+ id: 1,
+ required: 0,
+ data: {
+ type: 2
+ }
+ }, {
+ id: 2,
+ required: 0,
+ data: {
+ type: 12
+ }
+ }, {
+ id: 3,
+ required: 0,
+ img: {
+ type: 3
+ }
+ }, {
+ id: 4,
+ required: 0,
+ img: {
+ type: 1
+ }
+ }, {
+ id: 5,
+ required: 0,
+ data: {
+ type: 1
+ }
+ }
+ ],
+ ver: '1.2'
+}
+
const bidWithUndefinedFields = {
transactionId: 'au',
native: {
@@ -50,12 +154,12 @@ const bidWithUndefinedFields = {
clickUrl: 'https://www.link.example',
clickTrackers: ['https://tracker.example'],
impressionTrackers: ['https://impression.example'],
- javascriptTrackers: '',
+ javascriptTrackers: '',
ext: {
foo: 'foo-value',
- baz: undefined
- }
- }
+ baz: undefined,
+ },
+ },
};
describe('native.js', function () {
@@ -80,7 +184,9 @@ describe('native.js', function () {
const targeting = getNativeTargeting(bid);
expect(targeting[CONSTANTS.NATIVE_KEYS.title]).to.equal(bid.native.title);
expect(targeting[CONSTANTS.NATIVE_KEYS.body]).to.equal(bid.native.body);
- expect(targeting[CONSTANTS.NATIVE_KEYS.clickUrl]).to.equal(bid.native.clickUrl);
+ expect(targeting[CONSTANTS.NATIVE_KEYS.clickUrl]).to.equal(
+ bid.native.clickUrl
+ );
expect(targeting.hb_native_foo).to.equal(bid.native.foo);
});
@@ -92,19 +198,23 @@ describe('native.js', function () {
clickUrl: { sendId: true },
ext: {
foo: {
- sendId: false
+ sendId: false,
},
baz: {
- sendId: true
- }
- }
- }
+ sendId: true,
+ },
+ },
+ },
};
const targeting = getNativeTargeting(bid, deps(adUnit));
expect(targeting[CONSTANTS.NATIVE_KEYS.title]).to.equal(bid.native.title);
- expect(targeting[CONSTANTS.NATIVE_KEYS.body]).to.equal('hb_native_body:123');
- expect(targeting[CONSTANTS.NATIVE_KEYS.clickUrl]).to.equal('hb_native_linkurl:123');
+ expect(targeting[CONSTANTS.NATIVE_KEYS.body]).to.equal(
+ 'hb_native_body:123'
+ );
+ expect(targeting[CONSTANTS.NATIVE_KEYS.clickUrl]).to.equal(
+ 'hb_native_linkurl:123'
+ );
expect(targeting.hb_native_foo).to.equal(bid.native.ext.foo);
expect(targeting.hb_native_baz).to.equal('hb_native_baz:123');
});
@@ -117,13 +227,13 @@ describe('native.js', function () {
clickUrl: { sendId: true },
ext: {
foo: {
- required: false
+ required: false,
},
baz: {
- required: false
- }
- }
- }
+ required: false,
+ },
+ },
+ },
};
const targeting = getNativeTargeting(bidWithUndefinedFields, deps(adUnit));
@@ -132,7 +242,7 @@ describe('native.js', function () {
CONSTANTS.NATIVE_KEYS.title,
CONSTANTS.NATIVE_KEYS.sponsoredBy,
CONSTANTS.NATIVE_KEYS.clickUrl,
- 'hb_native_foo'
+ 'hb_native_foo',
]);
});
@@ -142,22 +252,19 @@ describe('native.js', function () {
nativeParams: {
image: {
required: true,
- sizes: [150, 50]
+ sizes: [150, 50],
},
title: {
required: true,
len: 80,
- sendTargetingKeys: true
+ sendTargetingKeys: true,
},
sendTargetingKeys: false,
- }
-
+ },
};
const targeting = getNativeTargeting(bid, deps(adUnit));
- expect(Object.keys(targeting)).to.deep.equal([
- CONSTANTS.NATIVE_KEYS.title
- ]);
+ expect(Object.keys(targeting)).to.deep.equal([CONSTANTS.NATIVE_KEYS.title]);
});
it('should only include targeting if sendTargetingKeys not set to false', function () {
@@ -166,38 +273,37 @@ describe('native.js', function () {
nativeParams: {
image: {
required: true,
- sizes: [150, 50]
+ sizes: [150, 50],
},
title: {
required: true,
- len: 80
+ len: 80,
},
body: {
- required: true
+ required: true,
},
clickUrl: {
- required: true
+ required: true,
},
icon: {
required: false,
- sendTargetingKeys: false
+ sendTargetingKeys: false,
},
cta: {
required: false,
- sendTargetingKeys: false
+ sendTargetingKeys: false,
},
sponsoredBy: {
required: false,
- sendTargetingKeys: false
+ sendTargetingKeys: false,
},
ext: {
foo: {
required: false,
- sendTargetingKeys: true
- }
- }
- }
-
+ sendTargetingKeys: true,
+ },
+ },
+ },
};
const targeting = getNativeTargeting(bid, deps(adUnit));
@@ -206,7 +312,7 @@ describe('native.js', function () {
CONSTANTS.NATIVE_KEYS.body,
CONSTANTS.NATIVE_KEYS.image,
CONSTANTS.NATIVE_KEYS.clickUrl,
- 'hb_native_foo'
+ 'hb_native_foo',
]);
});
@@ -216,17 +322,16 @@ describe('native.js', function () {
nativeParams: {
image: {
required: true,
- sizes: [150, 50]
+ sizes: [150, 50],
},
title: {
required: true,
len: 80,
},
rendererUrl: {
- url: 'https://www.renderer.com/'
- }
- }
-
+ url: 'https://www.renderer.com/',
+ },
+ },
};
const targeting = getNativeTargeting(bid, deps(adUnit));
@@ -238,7 +343,7 @@ describe('native.js', function () {
CONSTANTS.NATIVE_KEYS.icon,
CONSTANTS.NATIVE_KEYS.sponsoredBy,
CONSTANTS.NATIVE_KEYS.clickUrl,
- CONSTANTS.NATIVE_KEYS.rendererUrl
+ CONSTANTS.NATIVE_KEYS.rendererUrl,
]);
expect(bid.native.rendererUrl).to.deep.equal('https://www.renderer.com/');
@@ -251,15 +356,14 @@ describe('native.js', function () {
nativeParams: {
image: {
required: true,
- sizes: [150, 50]
+ sizes: [150, 50],
},
title: {
required: true,
len: 80,
},
- adTemplate: '##hb_native_body##<\/p><\/div>'
- }
-
+ adTemplate: '
',
+ },
};
const targeting = getNativeTargeting(bid, deps(adUnit));
@@ -270,10 +374,12 @@ describe('native.js', function () {
CONSTANTS.NATIVE_KEYS.image,
CONSTANTS.NATIVE_KEYS.icon,
CONSTANTS.NATIVE_KEYS.sponsoredBy,
- CONSTANTS.NATIVE_KEYS.clickUrl
+ CONSTANTS.NATIVE_KEYS.clickUrl,
]);
- expect(bid.native.adTemplate).to.deep.equal('
##hb_native_body##<\/p><\/div>');
+ expect(bid.native.adTemplate).to.deep.equal(
+ '
'
+ );
delete bid.native.adTemplate;
});
@@ -281,7 +387,10 @@ describe('native.js', function () {
fireNativeTrackers({}, bid);
sinon.assert.calledOnce(triggerPixelStub);
sinon.assert.calledWith(triggerPixelStub, bid.native.impressionTrackers[0]);
- sinon.assert.calledWith(insertHtmlIntoIframeStub, bid.native.javascriptTrackers);
+ sinon.assert.calledWith(
+ insertHtmlIntoIframeStub,
+ bid.native.javascriptTrackers
+ );
});
it('fires click trackers', function () {
@@ -291,7 +400,7 @@ describe('native.js', function () {
sinon.assert.calledWith(triggerPixelStub, bid.native.clickTrackers[0]);
});
- it('creates native asset message', function() {
+ it('creates native asset message', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'assetRequest',
@@ -304,92 +413,270 @@ describe('native.js', function () {
expect(message.assets.length).to.equal(3);
expect(message.assets).to.deep.include({
key: 'body',
- value: bid.native.body
+ value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
- value: bid.native.image.url
+ value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
- value: bid.native.clickUrl
+ value: bid.native.clickUrl,
});
});
- it('creates native all asset message', function() {
+ it('creates native all asset message', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};
- const message = getAllAssetsMessage(messageRequest, bid);
+ const message = getAllAssetsMessage(messageRequest, bid, {getNativeReq: () => null});
expect(message.assets.length).to.equal(9);
expect(message.assets).to.deep.include({
key: 'body',
- value: bid.native.body
+ value: bid.native.body,
});
expect(message.assets).to.deep.include({
key: 'image',
- value: bid.native.image.url
+ value: bid.native.image.url,
});
expect(message.assets).to.deep.include({
key: 'clickUrl',
- value: bid.native.clickUrl
+ value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
- value: bid.native.title
+ value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'icon',
- value: bid.native.icon.url
+ value: bid.native.icon.url,
});
expect(message.assets).to.deep.include({
key: 'cta',
- value: bid.native.cta
+ value: bid.native.cta,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
- value: bid.native.sponsoredBy
+ value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'foo',
- value: bid.native.ext.foo
+ value: bid.native.ext.foo,
});
expect(message.assets).to.deep.include({
key: 'baz',
- value: bid.native.ext.baz
+ value: bid.native.ext.baz,
});
});
- it('creates native all asset message with only defined fields', function() {
+ it('creates native all asset message with only defined fields', function () {
const messageRequest = {
message: 'Prebid Native',
action: 'allAssetRequest',
adId: '123',
};
- const message = getAllAssetsMessage(messageRequest, bidWithUndefinedFields);
+ const message = getAllAssetsMessage(messageRequest, bidWithUndefinedFields, {getNativeReq: () => null});
expect(message.assets.length).to.equal(4);
expect(message.assets).to.deep.include({
key: 'clickUrl',
- value: bid.native.clickUrl
+ value: bid.native.clickUrl,
});
expect(message.assets).to.deep.include({
key: 'title',
- value: bid.native.title
+ value: bid.native.title,
});
expect(message.assets).to.deep.include({
key: 'sponsoredBy',
- value: bid.native.sponsoredBy
+ value: bid.native.sponsoredBy,
});
expect(message.assets).to.deep.include({
key: 'foo',
- value: bid.native.ext.foo
+ value: bid.native.ext.foo,
+ });
+ });
+
+ it('creates native all asset message with OpenRTB format', function () {
+ const messageRequest = {
+ message: 'Prebid Native',
+ action: 'allAssetRequest',
+ adId: '123',
+ };
+
+ const message = getAllAssetsMessage(messageRequest, ortbBid, {getNativeReq: () => ortbRequest});
+
+ expect(message.assets.length).to.equal(8);
+ expect(message.assets).to.deep.include({
+ key: 'body',
+ value: bid.native.body,
+ });
+ expect(message.assets).to.deep.include({
+ key: 'image',
+ value: bid.native.image.url,
+ });
+ expect(message.assets).to.deep.include({
+ key: 'clickUrl',
+ value: bid.native.clickUrl,
+ });
+ expect(message.assets).to.deep.include({
+ key: 'title',
+ value: bid.native.title,
+ });
+ expect(message.assets).to.deep.include({
+ key: 'icon',
+ value: bid.native.icon.url,
+ });
+ expect(message.assets).to.deep.include({
+ key: 'cta',
+ value: bid.native.cta,
+ });
+ expect(message.assets).to.deep.include({
+ key: 'sponsoredBy',
+ value: bid.native.sponsoredBy,
});
+ expect(message.assets).to.deep.include({
+ key: 'privacyLink',
+ value: ortbBid.native.ortb.privacy,
+ });
+ });
+
+ const SAMPLE_ORTB_REQUEST = toOrtbNativeRequest({
+ title: 'vtitle',
+ body: 'vbody'
+ });
+ const SAMPLE_ORTB_RESPONSE = {
+ native: {
+ ortb: {
+ link: {
+ url: 'url'
+ },
+ assets: [
+ {
+ id: 0,
+ title: {
+ text: 'vtitle'
+ }
+ },
+ {
+ id: 1,
+ data: {
+ value: 'vbody'
+ }
+ }
+ ]
+ }
+ }
+ }
+ describe('getAllAssetsMessage', () => {
+ it('returns assets in legacy format for ortb responses', () => {
+ const actual = getAllAssetsMessage({}, SAMPLE_ORTB_RESPONSE, {getNativeReq: () => SAMPLE_ORTB_REQUEST});
+ expect(actual.assets).to.eql([
+ {
+ key: 'clickUrl',
+ value: 'url'
+ },
+ {
+ key: 'title',
+ value: 'vtitle'
+ },
+ {
+ key: 'body',
+ value: 'vbody'
+ },
+ ])
+ });
+ });
+ describe('getAssetsMessage', () => {
+ Object.entries({
+ 'hb_native_title': {key: 'title', value: 'vtitle'},
+ 'hb_native_body': {key: 'body', value: 'vbody'}
+ }).forEach(([tkey, assetVal]) => {
+ it(`returns ${tkey} asset in legacy format for ortb responses`, () => {
+ const actual = getAssetMessage({
+ assets: [tkey]
+ }, SAMPLE_ORTB_RESPONSE, {getNativeReq: () => SAMPLE_ORTB_REQUEST})
+ expect(actual.assets).to.eql([assetVal])
+ })
+ })
+ })
+});
+
+describe('validate native openRTB', function () {
+ it('should validate openRTB request', function () {
+ let openRTBNativeRequest = { assets: [] };
+ // assets array can't be empty
+ expect(isOpenRTBBidRequestValid(openRTBNativeRequest)).to.eq(false);
+ openRTBNativeRequest.assets.push({
+ id: 1.5,
+ required: 1,
+ title: {},
+ });
+
+ // asset.id must be integer
+ expect(isOpenRTBBidRequestValid(openRTBNativeRequest)).to.eq(false);
+ openRTBNativeRequest.assets[0].id = 1;
+ // title must have 'len' property
+ expect(isOpenRTBBidRequestValid(openRTBNativeRequest)).to.eq(false);
+ openRTBNativeRequest.assets[0].title.len = 140;
+ // openRTB request is valid
+ expect(isOpenRTBBidRequestValid(openRTBNativeRequest)).to.eq(true);
+
+ openRTBNativeRequest.assets.push({
+ id: 2,
+ required: 1,
+ video: {
+ mimes: [],
+ protocols: [],
+ minduration: 50,
+ },
+ });
+ // video asset should have all required properties
+ expect(isOpenRTBBidRequestValid(openRTBNativeRequest)).to.eq(false);
+ openRTBNativeRequest.assets[1].video.maxduration = 60;
+ expect(isOpenRTBBidRequestValid(openRTBNativeRequest)).to.eq(true);
+ });
+
+ it('should validate openRTB native bid', function () {
+ const openRTBRequest = {
+ assets: [
+ {
+ id: 1,
+ required: 1,
+ },
+ {
+ id: 2,
+ required: 0,
+ },
+ {
+ id: 3,
+ required: 1,
+ },
+ ],
+ };
+ let openRTBBid = {
+ assets: [
+ {
+ id: 1,
+ },
+ {
+ id: 2,
+ },
+ ],
+ };
+
+ // link is missing
+ expect(isNativeOpenRTBBidValid(openRTBBid, openRTBRequest)).to.eq(false);
+ openRTBBid.link = { url: 'www.foo.bar' };
+ // required id == 3 is missing
+ expect(isNativeOpenRTBBidValid(openRTBBid, openRTBRequest)).to.eq(false);
+
+ openRTBBid.assets[1].id = 3;
+ expect(isNativeOpenRTBBidValid(openRTBBid, openRTBRequest)).to.eq(true);
});
});
@@ -407,15 +694,15 @@ describe('validate native', function () {
image: {
required: true,
sizes: [150, 50],
- aspect_ratios: [150, 50]
+ aspect_ratios: [150, 50],
},
icon: {
required: true,
- sizes: [50, 50]
+ sizes: [50, 50],
},
- }
- }
- }
+ },
+ },
+ };
let validBid = {
adId: 'abc123',
@@ -424,23 +711,24 @@ describe('validate native', function () {
adUnitCode: '123/prebid_native_adunit',
bidder: 'test_bidder',
native: {
- body: 'This is a Prebid Native Creative. There are many like it, but this one is mine.',
+ body:
+ 'This is a Prebid Native Creative. There are many like it, but this one is mine.',
clickTrackers: ['http://my.click.tracker/url'],
icon: {
url: 'http://my.image.file/ad_image.jpg',
height: 75,
- width: 75
+ width: 75,
},
image: {
url: 'http://my.icon.file/ad_icon.jpg',
height: 2250,
- width: 3000
+ width: 3000,
},
clickUrl: 'http://prebid.org/dev-docs/show-native-ads.html',
impressionTrackers: ['http://my.imp.tracker/url'],
- javascriptTrackers: '',
- title: 'This is an example Prebid Native creative'
- }
+ javascriptTrackers: '',
+ title: 'This is an example Prebid Native creative',
+ },
};
let noIconDimBid = {
@@ -450,19 +738,20 @@ describe('validate native', function () {
adUnitCode: '123/prebid_native_adunit',
bidder: 'test_bidder',
native: {
- body: 'This is a Prebid Native Creative. There are many like it, but this one is mine.',
+ body:
+ 'This is a Prebid Native Creative. There are many like it, but this one is mine.',
clickTrackers: ['http://my.click.tracker/url'],
icon: 'http://my.image.file/ad_image.jpg',
image: {
url: 'http://my.icon.file/ad_icon.jpg',
height: 2250,
- width: 3000
+ width: 3000,
},
clickUrl: 'http://prebid.org/dev-docs/show-native-ads.html',
impressionTrackers: ['http://my.imp.tracker/url'],
- javascriptTrackers: '',
- title: 'This is an example Prebid Native creative'
- }
+ javascriptTrackers: '',
+ title: 'This is an example Prebid Native creative',
+ },
};
let noImgDimBid = {
@@ -472,19 +761,20 @@ describe('validate native', function () {
adUnitCode: '123/prebid_native_adunit',
bidder: 'test_bidder',
native: {
- body: 'This is a Prebid Native Creative. There are many like it, but this one is mine.',
+ body:
+ 'This is a Prebid Native Creative. There are many like it, but this one is mine.',
clickTrackers: ['http://my.click.tracker/url'],
icon: {
url: 'http://my.image.file/ad_image.jpg',
height: 75,
- width: 75
+ width: 75,
},
image: 'http://my.icon.file/ad_icon.jpg',
clickUrl: 'http://prebid.org/dev-docs/show-native-ads.html',
impressionTrackers: ['http://my.imp.tracker/url'],
- javascriptTrackers: '',
- title: 'This is an example Prebid Native creative'
- }
+ javascriptTrackers: '',
+ title: 'This is an example Prebid Native creative',
+ },
};
beforeEach(function () {});
@@ -493,12 +783,508 @@ describe('validate native', function () {
it('should accept bid if no image sizes are defined', function () {
decorateAdUnitsWithNativeParams([adUnit]);
- const index = stubAuctionIndex({adUnits: [adUnit]})
- let result = nativeBidIsValid(validBid, {index});
+ const index = stubAuctionIndex({ adUnits: [adUnit] });
+ let result = nativeBidIsValid(validBid, { index });
expect(result).to.be.true;
- result = nativeBidIsValid(noIconDimBid, {index});
+ result = nativeBidIsValid(noIconDimBid, { index });
expect(result).to.be.true;
- result = nativeBidIsValid(noImgDimBid, {index});
+ result = nativeBidIsValid(noImgDimBid, { index });
expect(result).to.be.true;
});
+
+ it('should convert from old-style native to OpenRTB request', () => {
+ const adUnit = {
+ transactionId: 'test_adunit',
+ mediaTypes: {
+ native: {
+ title: {
+ required: true,
+ },
+ body: {
+ required: true,
+ len: 45
+ },
+ image: {
+ required: true,
+ sizes: [150, 50],
+ aspect_ratios: [{
+ min_width: 150,
+ min_height: 50
+ }]
+ },
+ icon: {
+ required: true,
+ aspect_ratios: [{
+ min_width: 150,
+ min_height: 50
+ }]
+ },
+ address: {},
+ },
+ },
+ };
+
+ const ortb = toOrtbNativeRequest(adUnit.mediaTypes.native);
+ expect(ortb).to.be.a('object');
+ expect(ortb.assets).to.be.a('array');
+
+ // title
+ expect(ortb.assets[0]).to.deep.include({
+ id: 0,
+ required: 1,
+ title: {
+ len: 140
+ }
+ });
+
+ // body => data
+ expect(ortb.assets[1]).to.deep.include({
+ id: 1,
+ required: 1,
+ data: {
+ type: 2,
+ len: 45
+ }
+ });
+
+ // image => image
+ expect(ortb.assets[2]).to.deep.include({
+ id: 2,
+ required: 1,
+ img: {
+ type: 3, // Main Image
+ w: 150,
+ h: 50,
+ }
+ });
+
+ expect(ortb.assets[3]).to.deep.include({
+ id: 3,
+ required: 1,
+ img: {
+ type: 1, // Icon Image
+ wmin: 150,
+ hmin: 50,
+ }
+ });
+
+ expect(ortb.assets[4]).to.deep.include({
+ id: 4,
+ required: 0,
+ data: {
+ type: 9,
+ }
+ });
+ });
+
+ ['bogusKey', 'clickUrl', 'privacyLink'].forEach(nativeKey => {
+ it(`should not generate an empty asset for key ${nativeKey}`, () => {
+ const ortbReq = toOrtbNativeRequest({
+ [nativeKey]: {
+ required: true
+ }
+ });
+ expect(ortbReq.assets.length).to.equal(0);
+ });
+ })
+
+ it('should convert from ortb to old-style native request', () => {
+ const openRTBRequest = {
+ 'ver': '1.2',
+ 'context': 2,
+ 'contextsubtype': 20,
+ 'plcmttype': 11,
+ 'plcmtcnt': 1,
+ 'aurlsupport': 0,
+ 'privacy': 1,
+ 'eventrackers': [
+ {
+ 'event': 1,
+ 'methods': [1, 2]
+ },
+ {
+ 'event': 2,
+ 'methods': [1]
+ }
+ ],
+ 'assets': [
+ {
+ 'id': 123,
+ 'required': 1,
+ 'title': {
+ 'len': 140
+ }
+ },
+ {
+ 'id': 128,
+ 'required': 0,
+ 'img': {
+ 'wmin': 836,
+ 'hmin': 627,
+ 'type': 3
+ }
+ },
+ {
+ 'id': 124,
+ 'required': 1,
+ 'img': {
+ 'wmin': 50,
+ 'hmin': 50,
+ 'type': 1
+ }
+ },
+ {
+ 'id': 126,
+ 'required': 1,
+ 'data': {
+ 'type': 1,
+ 'len': 25
+ }
+ },
+ {
+ 'id': 127,
+ 'required': 1,
+ 'data': {
+ 'type': 2,
+ 'len': 140
+ }
+ }
+ ]
+ };
+
+ const oldNativeRequest = fromOrtbNativeRequest(openRTBRequest);
+
+ expect(oldNativeRequest).to.be.a('object');
+ expect(oldNativeRequest.title).to.include({
+ required: true,
+ len: 140
+ });
+
+ expect(oldNativeRequest.image).to.deep.include({
+ required: false,
+ aspect_ratios: {
+ min_width: 836,
+ min_height: 627,
+ ratio_width: 836,
+ ratio_height: 627
+ }
+ });
+
+ expect(oldNativeRequest.icon).to.deep.include({
+ required: true,
+ aspect_ratios: {
+ min_width: 50,
+ min_height: 50,
+ ratio_width: 50,
+ ratio_height: 50
+ }
+ });
+ expect(oldNativeRequest.sponsoredBy).to.include({
+ required: true,
+ len: 25
+ })
+ expect(oldNativeRequest.body).to.include({
+ required: true,
+ len: 140
+ })
+ });
+
+ if (FEATURES.NATIVE) {
+ it('should convert ortb bid requests to proprietary requests', () => {
+ const validBidRequests = [{
+ bidId: 'bidId3',
+ adUnitCode: 'adUnitCode3',
+ transactionId: 'transactionId3',
+ mediaTypes: {
+ banner: {}
+ },
+ params: {
+ publisher: 'publisher2',
+ placement: 'placement3'
+ }
+ }];
+ const resultRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
+ expect(resultRequests).to.be.deep.equals(validBidRequests);
+
+ validBidRequests[0].mediaTypes.native = {
+ ortb: {
+ ver: '1.2',
+ context: 2,
+ contextsubtype: 20,
+ plcmttype: 11,
+ plcmtcnt: 1,
+ aurlsupport: 0,
+ privacy: 1,
+ eventrackers: [
+ {
+ event: 1,
+ methods: [1, 2]
+ },
+ {
+ event: 2,
+ methods: [1]
+ }
+ ],
+ assets: [
+ {
+ id: 123,
+ required: 1,
+ title: {
+ len: 140
+ }
+ },
+ {
+ id: 128,
+ required: 0,
+ img: {
+ wmin: 836,
+ hmin: 627,
+ type: 3
+ }
+ },
+ {
+ id: 124,
+ required: 1,
+ img: {
+ wmin: 50,
+ hmin: 50,
+ type: 1
+ }
+ },
+ {
+ id: 126,
+ required: 1,
+ data: {
+ type: 1,
+ len: 25
+ }
+ },
+ {
+ id: 127,
+ required: 1,
+ data: {
+ type: 2,
+ len: 140
+ }
+ }
+ ]
+ }
+ };
+
+ const resultRequests2 = convertOrtbRequestToProprietaryNative(validBidRequests);
+ expect(resultRequests2[0].mediaTypes.native).to.deep.include({
+ title: {
+ required: true,
+ len: 140
+ },
+ icon: {
+ required: true,
+ aspect_ratios: {
+ min_width: 50,
+ min_height: 50,
+ ratio_width: 50,
+ ratio_height: 50
+ }
+ },
+ sponsoredBy: {
+ required: true,
+ len: 25
+ },
+ body: {
+ required: true,
+ len: 140
+ }
+ });
+ });
+ }
});
+
+describe('legacyPropertiesToOrtbNative', () => {
+ describe('click trakckers', () => {
+ it('should convert clickUrl to link.url', () => {
+ const native = legacyPropertiesToOrtbNative({clickUrl: 'some-url'});
+ expect(native.link.url).to.eql('some-url');
+ });
+ it('should convert single clickTrackers to link.clicktrackers', () => {
+ const native = legacyPropertiesToOrtbNative({clickTrackers: 'some-url'});
+ expect(native.link.clicktrackers).to.eql([
+ 'some-url'
+ ])
+ });
+ it('should convert multiple clickTrackers into link.clicktrackers', () => {
+ const native = legacyPropertiesToOrtbNative({clickTrackers: ['url1', 'url2']});
+ expect(native.link.clicktrackers).to.eql([
+ 'url1',
+ 'url2'
+ ])
+ })
+ });
+ describe('impressionTrackers', () => {
+ it('should convert a single tracker into an eventtracker entry', () => {
+ const native = legacyPropertiesToOrtbNative({impressionTrackers: 'some-url'});
+ expect(native.eventtrackers).to.eql([
+ {
+ event: 1,
+ method: 1,
+ url: 'some-url'
+ }
+ ]);
+ });
+
+ it('should convert an array into corresponding eventtracker entries', () => {
+ const native = legacyPropertiesToOrtbNative({impressionTrackers: ['url1', 'url2']});
+ expect(native.eventtrackers).to.eql([
+ {
+ event: 1,
+ method: 1,
+ url: 'url1'
+ },
+ {
+ event: 1,
+ method: 1,
+ url: 'url2'
+ }
+ ])
+ })
+ });
+ describe('javascriptTrackers', () => {
+ it('should convert a single value into jstracker', () => {
+ const native = legacyPropertiesToOrtbNative({javascriptTrackers: 'some-markup'});
+ expect(native.jstracker).to.eql('some-markup');
+ })
+ it('should merge multiple values into a single jstracker', () => {
+ const native = legacyPropertiesToOrtbNative({javascriptTrackers: ['some-markup', 'some-other-markup']});
+ expect(native.jstracker).to.eql('some-markupsome-other-markup');
+ })
+ });
+});
+
+describe('fireImpressionTrackers', () => {
+ let runMarkup, fetchURL;
+ beforeEach(() => {
+ runMarkup = sinon.stub();
+ fetchURL = sinon.stub();
+ })
+
+ function runTrackers(resp) {
+ fireImpressionTrackers(resp, {runMarkup, fetchURL})
+ }
+
+ it('should run markup in jstracker', () => {
+ runTrackers({
+ jstracker: 'some-markup'
+ });
+ sinon.assert.calledWith(runMarkup, 'some-markup');
+ });
+
+ it('should fetch each url in imptrackers', () => {
+ const urls = ['url1', 'url2'];
+ runTrackers({
+ imptrackers: urls
+ });
+ urls.forEach(url => sinon.assert.calledWith(fetchURL, url));
+ });
+
+ it('should fetch each url in eventtrackers that use the image method', () => {
+ const urls = ['url1', 'url2'];
+ runTrackers({
+ eventtrackers: urls.map(url => ({event: 1, method: 1, url}))
+ });
+ urls.forEach(url => sinon.assert.calledWith(fetchURL, url))
+ });
+
+ it('should load as a script each url in eventtrackers that use the js method', () => {
+ const urls = ['url1', 'url2'];
+ runTrackers({
+ eventtrackers: urls.map(url => ({event: 1, method: 2, url}))
+ });
+ urls.forEach(url => sinon.assert.calledWith(runMarkup, sinon.match(`script async src="${url}"`)))
+ });
+
+ it('should not fire trackers that are not impression trakcers', () => {
+ runTrackers({
+ link: {
+ clicktrackers: ['click-url']
+ },
+ eventtrackers: [{
+ event: 2, // not imp
+ method: 1,
+ url: 'some-url'
+ }]
+ });
+ sinon.assert.notCalled(fetchURL);
+ sinon.assert.notCalled(runMarkup);
+ })
+})
+
+describe('fireClickTrackers', () => {
+ let fetchURL;
+ beforeEach(() => {
+ fetchURL = sinon.stub();
+ });
+
+ function runTrackers(resp, assetId = null) {
+ fireClickTrackers(resp, assetId, {fetchURL});
+ }
+
+ it('should load each URL in link.clicktrackers', () => {
+ const urls = ['url1', 'url2'];
+ runTrackers({
+ link: {
+ clicktrackers: urls
+ }
+ });
+ urls.forEach(url => sinon.assert.calledWith(fetchURL, url));
+ })
+
+ it('should load each URL in asset.link.clicktrackers, when response is ORTB', () => {
+ const urls = ['asset_url1', 'asset_url2'];
+ runTrackers({
+ assets: [
+ {
+ id: 1,
+ link: {
+ clicktrackers: urls
+ }
+ }
+ ],
+ }, 1);
+ urls.forEach(url => sinon.assert.calledWith(fetchURL, url));
+ })
+})
+
+describe('toOrtbNativeResponse', () => {
+ it('should work when there are unrequested assets in the response', () => {
+ const legacyResponse = {
+ 'title': 'vtitle',
+ 'body': 'vbody'
+ }
+ const request = toOrtbNativeRequest({
+ title: {
+ required: 'true'
+ },
+
+ });
+ const ortbResponse = toOrtbNativeResponse(legacyResponse, request);
+ expect(ortbResponse.assets.length).to.eql(1);
+ });
+
+ it('should not modify the request', () => {
+ const legacyResponse = {
+ title: 'vtitle'
+ }
+ const request = toOrtbNativeRequest({
+ title: {
+ required: true
+ }
+ });
+ const requestCopy = JSON.parse(JSON.stringify(request));
+ const response = toOrtbNativeResponse(legacyResponse, request);
+ expect(request).to.eql(requestCopy);
+ sinon.assert.match(response.assets[0], {
+ title: {
+ text: 'vtitle'
+ }
+ })
+ })
+})
diff --git a/test/spec/refererDetection_spec.js b/test/spec/refererDetection_spec.js
index a404e4f883e..3f33d1646a1 100644
--- a/test/spec/refererDetection_spec.js
+++ b/test/spec/refererDetection_spec.js
@@ -1,6 +1,6 @@
-import { detectReferer } from 'src/refererDetection.js';
-import { config } from 'src/config.js';
-import { expect } from 'chai';
+import {detectReferer, ensureProtocol, parseDomain} from 'src/refererDetection.js';
+import {config} from 'src/config.js';
+import {expect} from 'chai';
/**
* Build a walkable linked list of window-like objects for testing.
@@ -11,13 +11,13 @@ import { expect } from 'chai';
* @param {boolean} [ancestorOrigins]
* @returns {Object}
*/
-function buildWindowTree(urls, topReferrer = '', canonicalUrl = null, ancestorOrigins = false) {
+function buildWindowTree(urls, topReferrer = null, canonicalUrl = null, ancestorOrigins = false) {
/**
- * Find the origin from a given fully-qualified URL.
- *
- * @param {string} url The fully qualified URL
- * @returns {string|null}
- */
+ * Find the origin from a given fully-qualified URL.
+ *
+ * @param {string} url The fully qualified URL
+ * @returns {string|null}
+ */
function getOrigin(url) {
const originRegex = new RegExp('^(https?://[^/]+/?)');
@@ -30,83 +30,89 @@ function buildWindowTree(urls, topReferrer = '', canonicalUrl = null, ancestorOr
return null;
}
- let previousWindow;
- const myOrigin = getOrigin(urls[urls.length - 1]);
+ const inaccessibles = [];
- const windowList = urls.map((url, index) => {
- const theirOrigin = getOrigin(url),
- sameOrigin = (myOrigin === theirOrigin);
-
- const win = {};
-
- if (sameOrigin) {
- win.location = {
- href: url
- };
+ let previousWindow, topWindow;
+ const topOrigin = getOrigin(urls[0]);
- if (ancestorOrigins) {
- win.location.ancestorOrigins = urls.slice(0, index).reverse().map(getOrigin);
+ const windowList = urls.map((url, index) => {
+ const thisOrigin = getOrigin(url),
+ sameOriginAsPrevious = index === 0 ? true : (getOrigin(urls[index - 1]) === thisOrigin),
+ sameOriginAsTop = thisOrigin === topOrigin;
+
+ const win = {
+ location: {
+ href: url,
+ },
+ document: {
+ referrer: index === 0 ? topReferrer : urls[index - 1]
}
-
- if (index === 0) {
- win.document = {
- referrer: topReferrer
- };
-
- if (canonicalUrl) {
- win.document.querySelector = function(selector) {
- if (selector === "link[rel='canonical']") {
- return {
- href: canonicalUrl
- };
- }
-
- return null;
+ };
+
+ if (topWindow == null) {
+ topWindow = win;
+ win.document.querySelector = function (selector) {
+ if (selector === 'link[rel=\'canonical\']') {
+ return {
+ href: canonicalUrl
};
}
- } else {
- win.document = {
- referrer: urls[index - 1]
- };
- }
+ return null;
+ };
}
+ if (sameOriginAsPrevious) {
+ win.parent = previousWindow;
+ } else {
+ win.parent = inaccessibles[inaccessibles.length - 1];
+ }
+ if (ancestorOrigins) {
+ win.location.ancestorOrigins = urls.slice(0, index).reverse().map(getOrigin);
+ }
+ win.top = sameOriginAsTop ? topWindow : inaccessibles[0];
+
+ const inWin = {parent: inaccessibles[inaccessibles.length - 1], top: inaccessibles[0]};
+ if (index === 0) {
+ inWin.top = inWin;
+ }
+ ['document', 'location'].forEach((prop) => {
+ Object.defineProperty(inWin, prop, {
+ get: function () {
+ throw new Error('cross-origin access');
+ }
+ });
+ });
+ inaccessibles.push(inWin);
previousWindow = win;
return win;
});
- const topWindow = windowList[0];
-
- previousWindow = null;
-
- windowList.forEach((win) => {
- win.top = topWindow;
- win.parent = previousWindow || topWindow;
- previousWindow = win;
- });
-
return windowList[windowList.length - 1];
}
describe('Referer detection', () => {
+ afterEach(function () {
+ config.resetConfig();
+ });
+
describe('Non cross-origin scenarios', () => {
describe('No iframes', () => {
- afterEach(function () {
- config.resetConfig();
- });
-
it('Should return the current window location and no canonical URL', () => {
const testWindow = buildWindowTree(['https://example.com/some/page'], 'https://othersite.com/'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page',
+ location: 'https://example.com/some/page',
reachedTop: true,
isAmp: false,
numIframes: 0,
stack: ['https://example.com/some/page'],
- canonicalUrl: null
+ canonicalUrl: null,
+ page: 'https://example.com/some/page',
+ ref: 'https://othersite.com/',
+ domain: 'example.com',
});
});
@@ -114,13 +120,17 @@ describe('Referer detection', () => {
const testWindow = buildWindowTree(['https://example.com/some/page'], 'https://othersite.com/', 'https://example.com/canonical/page'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page',
+ location: 'https://example.com/some/page',
reachedTop: true,
isAmp: false,
numIframes: 0,
stack: ['https://example.com/some/page'],
- canonicalUrl: 'https://example.com/canonical/page'
+ canonicalUrl: 'https://example.com/canonical/page',
+ page: 'https://example.com/canonical/page',
+ ref: 'https://othersite.com/',
+ domain: 'example.com'
});
});
});
@@ -130,8 +140,9 @@ describe('Referer detection', () => {
const testWindow = buildWindowTree(['https://example.com/some/page', 'https://example.com/other/page', 'https://example.com/third/page'], 'https://othersite.com/'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page',
+ location: 'https://example.com/some/page',
reachedTop: true,
isAmp: false,
numIframes: 2,
@@ -140,7 +151,10 @@ describe('Referer detection', () => {
'https://example.com/other/page',
'https://example.com/third/page'
],
- canonicalUrl: null
+ canonicalUrl: null,
+ page: 'https://example.com/some/page',
+ ref: 'https://othersite.com/',
+ domain: 'example.com'
});
});
@@ -148,8 +162,9 @@ describe('Referer detection', () => {
const testWindow = buildWindowTree(['https://example.com/some/page', 'https://example.com/other/page', 'https://example.com/third/page'], 'https://othersite.com/', 'https://example.com/canonical/page'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page',
+ location: 'https://example.com/some/page',
reachedTop: true,
isAmp: false,
numIframes: 2,
@@ -158,18 +173,22 @@ describe('Referer detection', () => {
'https://example.com/other/page',
'https://example.com/third/page'
],
- canonicalUrl: 'https://example.com/canonical/page'
+ canonicalUrl: 'https://example.com/canonical/page',
+ page: 'https://example.com/canonical/page',
+ ref: 'https://othersite.com/',
+ domain: 'example.com'
});
});
- it('Should override canonical URL with config pageUrl', () => {
- config.setConfig({'pageUrl': 'testUrl.com'});
+ it('Should override canonical URL (and page) with config pageUrl', () => {
+ config.setConfig({'pageUrl': 'https://testurl.com'});
const testWindow = buildWindowTree(['https://example.com/some/page', 'https://example.com/other/page', 'https://example.com/third/page'], 'https://othersite.com/', 'https://example.com/canonical/page'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page',
+ location: 'https://example.com/some/page',
reachedTop: true,
isAmp: false,
numIframes: 2,
@@ -178,7 +197,10 @@ describe('Referer detection', () => {
'https://example.com/other/page',
'https://example.com/third/page'
],
- canonicalUrl: 'testUrl.com'
+ canonicalUrl: 'https://testurl.com',
+ page: 'https://testurl.com',
+ ref: 'https://othersite.com/',
+ domain: 'testurl.com'
});
});
});
@@ -189,8 +211,9 @@ describe('Referer detection', () => {
const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad'], 'https://othersite.com/', 'https://canonical.example.com/'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page',
+ sinon.assert.match(result, {
+ location: 'https://example.com/some/page',
+ topmostLocation: 'https://example.com/some/page',
reachedTop: true,
isAmp: false,
numIframes: 1,
@@ -198,7 +221,10 @@ describe('Referer detection', () => {
'https://example.com/some/page',
'https://safe.frame/ad'
],
- canonicalUrl: null
+ canonicalUrl: null,
+ page: 'https://example.com/some/page',
+ ref: null,
+ domain: 'example.com'
});
});
@@ -206,8 +232,9 @@ describe('Referer detection', () => {
const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad', 'https://safe.frame/ad'], 'https://othersite.com/', 'https://canonical.example.com/'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page',
+ location: 'https://example.com/some/page',
reachedTop: true,
isAmp: false,
numIframes: 2,
@@ -216,16 +243,20 @@ describe('Referer detection', () => {
'https://safe.frame/ad',
'https://safe.frame/ad'
],
- canonicalUrl: null
+ canonicalUrl: null,
+ page: 'https://example.com/some/page',
+ ref: null,
+ domain: 'example.com',
});
});
- it('Should return the second iframe location with three cross-origin windows and no ancessorOrigins', () => {
+ it('Should return the second iframe location with three cross-origin windows and no ancestorOrigins', () => {
const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad', 'https://otherfr.ame/ad'], 'https://othersite.com/', 'https://canonical.example.com/'),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://safe.frame/ad',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://safe.frame/ad',
+ location: null,
reachedTop: false,
isAmp: false,
numIframes: 2,
@@ -234,16 +265,20 @@ describe('Referer detection', () => {
'https://safe.frame/ad',
'https://otherfr.ame/ad'
],
- canonicalUrl: null
+ canonicalUrl: null,
+ page: null,
+ ref: null,
+ domain: null
});
});
- it('Should return the top window origin with three cross-origin windows with ancessorOrigins', () => {
+ it('Should return the top window origin with three cross-origin windows with ancestorOrigins', () => {
const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad', 'https://otherfr.ame/ad'], 'https://othersite.com/', 'https://canonical.example.com/', true),
result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/',
+ location: 'https://example.com/',
reachedTop: false,
isAmp: false,
numIframes: 2,
@@ -252,7 +287,10 @@ describe('Referer detection', () => {
'https://safe.frame/ad',
'https://otherfr.ame/ad'
],
- canonicalUrl: null
+ canonicalUrl: null,
+ page: 'https://example.com/',
+ ref: null,
+ domain: 'example.com'
});
});
});
@@ -268,8 +306,9 @@ describe('Referer detection', () => {
const result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page/amp/',
+ sinon.assert.match(result, {
+ location: 'https://example.com/some/page/amp/',
+ topmostLocation: 'https://example.com/some/page/amp/',
reachedTop: true,
isAmp: true,
numIframes: 1,
@@ -277,7 +316,10 @@ describe('Referer detection', () => {
'https://example.com/some/page/amp/',
'https://ad-iframe.ampproject.org/ad'
],
- canonicalUrl: 'https://example.com/some/page/'
+ canonicalUrl: 'https://example.com/some/page/',
+ page: 'https://example.com/some/page/',
+ ref: null,
+ domain: 'example.com'
});
});
@@ -291,8 +333,9 @@ describe('Referer detection', () => {
const result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page/amp/',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page/amp/',
+ location: 'https://example.com/some/page/amp/',
reachedTop: true,
isAmp: true,
numIframes: 1,
@@ -300,10 +343,24 @@ describe('Referer detection', () => {
'https://example.com/some/page/amp/',
'https://ad-iframe.ampproject.org/ad'
],
- canonicalUrl: 'https://example.com/some/page/'
+ canonicalUrl: 'https://example.com/some/page/',
+ page: 'https://example.com/some/page/',
+ ref: null,
+ domain: 'example.com'
});
});
+ it('should respect pageUrl as the primary source of canonicalUrl', () => {
+ config.setConfig({
+ pageUrl: 'pub-defined'
+ });
+ const w = buildWindowTree(['https://example.com', 'https://amp.com']);
+ w.context = {
+ canonicalUrl: 'should-be-overridden'
+ };
+ expect(detectReferer(w)().canonicalUrl).to.equal('pub-defined');
+ });
+
describe('Cached AMP page in iframed search result', () => {
it('Should return the AMP source and canonical URLs but with a null top-level stack location Without ancesorOrigins', () => {
const testWindow = buildWindowTree(['https://google.com/amp/example-com/some/page/amp/', 'https://example-com.amp-cache.example.com/some/page/amp/', 'https://ad-iframe.ampproject.org/ad']);
@@ -315,8 +372,9 @@ describe('Referer detection', () => {
const result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page/amp/',
+ sinon.assert.match(result, {
+ topmostLocation: 'https://example.com/some/page/amp/',
+ location: 'https://example.com/some/page/amp/',
reachedTop: false,
isAmp: true,
numIframes: 2,
@@ -325,7 +383,10 @@ describe('Referer detection', () => {
'https://example.com/some/page/amp/',
'https://ad-iframe.ampproject.org/ad'
],
- canonicalUrl: 'https://example.com/some/page/'
+ canonicalUrl: 'https://example.com/some/page/',
+ page: 'https://example.com/some/page/',
+ ref: null,
+ domain: 'example.com',
});
});
@@ -339,8 +400,9 @@ describe('Referer detection', () => {
const result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page/amp/',
+ sinon.assert.match(result, {
+ location: 'https://example.com/some/page/amp/',
+ topmostLocation: 'https://example.com/some/page/amp/',
reachedTop: false,
isAmp: true,
numIframes: 2,
@@ -349,7 +411,10 @@ describe('Referer detection', () => {
'https://example.com/some/page/amp/',
'https://ad-iframe.ampproject.org/ad'
],
- canonicalUrl: 'https://example.com/some/page/'
+ canonicalUrl: 'https://example.com/some/page/',
+ page: 'https://example.com/some/page/',
+ ref: null,
+ domain: 'example.com'
});
});
@@ -363,8 +428,9 @@ describe('Referer detection', () => {
const result = detectReferer(testWindow)();
- expect(result).to.deep.equal({
- referer: 'https://example.com/some/page/amp/',
+ sinon.assert.match(result, {
+ location: 'https://example.com/some/page/amp/',
+ topmostLocation: 'https://example.com/some/page/amp/',
reachedTop: false,
isAmp: true,
numIframes: 3,
@@ -374,9 +440,105 @@ describe('Referer detection', () => {
'https://ad-iframe.ampproject.org/ad',
'https://ad-iframe.ampproject.org/ad'
],
- canonicalUrl: 'https://example.com/some/page/'
+ canonicalUrl: 'https://example.com/some/page/',
+ page: 'https://example.com/some/page/',
+ ref: null,
+ domain: 'example.com',
});
});
});
});
});
+
+describe('ensureProtocol', () => {
+ ['', null, undefined].forEach((val) => {
+ it(`should return unchanged invalid input: ${val}`, () => {
+ expect(ensureProtocol(val)).to.eql(val);
+ });
+ });
+
+ ['http:', 'https:'].forEach((protocol) => {
+ Object.entries({
+ 'window.top.location.protocol': {
+ top: {
+ location: {
+ protocol
+ }
+ },
+ location: {
+ protocol: 'unused'
+ }
+ },
+ 'window.location.protocol': (() => {
+ const w = {
+ top: {},
+ location: {
+ protocol
+ }
+ };
+ Object.defineProperty(w.top, 'location', {
+ get: function () {
+ throw new Error('cross-origin');
+ }
+ });
+ return w;
+ })(),
+ }).forEach(([t, win]) => {
+ describe(`when ${t} declares ${protocol}`, () => {
+ Object.entries({
+ 'declared': {
+ url: 'proto://example.com/page',
+ expect: 'proto://example.com/page'
+ },
+ 'relative': {
+ url: '//example.com/page',
+ expect: `${protocol}//example.com/page`
+ },
+ 'missing': {
+ url: 'example.com/page',
+ expect: `${protocol}//example.com/page`
+ }
+ }).forEach(([t, {url, expect: expected}]) => {
+ it(`should handle URLs with ${t} protocols`, () => {
+ expect(ensureProtocol(url, win)).to.equal(expected);
+ });
+ });
+ });
+ });
+ });
+});
+
+describe('parseDomain', () => {
+ Object.entries({
+ 'www.example.com': 'www.example.com',
+ 'example.com:443': 'example.com:443',
+ 'www.sub.example.com': 'www.sub.example.com',
+ 'example.com/page': 'example.com',
+ 'www.example.com:443/page': 'www.example.com:443',
+ 'http://www.example.com:443/page?query=value': 'www.example.com:443',
+ '': undefined,
+ }).forEach(([input, expected]) => {
+ it(`should extract domain from '${input}' -> '${expected}`, () => {
+ expect(parseDomain(input)).to.equal(expected);
+ });
+ });
+ Object.entries({
+ 'www.example.com': 'example.com',
+ 'https://www.sub.example.com': 'sub.example.com',
+ '//www.example.com:443': 'example.com:443',
+ 'without.www.example.com': 'without.www.example.com'
+ }).forEach(([input, expected]) => {
+ it('should remove leading www if requested', () => {
+ expect(parseDomain(input, {noLeadingWww: true})).to.equal(expected);
+ })
+ });
+ Object.entries({
+ 'example.com:443': 'example.com',
+ 'https://sub.example.com': 'sub.example.com',
+ 'http://sub.example.com:8443': 'sub.example.com'
+ }).forEach(([input, expected]) => {
+ it('should remove port if requested', () => {
+ expect(parseDomain(input, {noPort: true})).to.equal(expected);
+ })
+ })
+});
diff --git a/test/spec/renderer_spec.js b/test/spec/renderer_spec.js
index 6de06606136..c41334f916a 100644
--- a/test/spec/renderer_spec.js
+++ b/test/spec/renderer_spec.js
@@ -107,6 +107,21 @@ describe('Renderer', function () {
sinon.assert.calledOnce(func2);
expect(testRenderer1.cmd.length).to.equal(0);
});
+
+ it('renders immediately when requested', function () {
+ const testRenderer3 = Renderer.install({
+ url: 'https://httpbin.org/post',
+ config: { test: 'config2' },
+ id: 2,
+ renderNow: true
+ });
+ const func1 = sinon.spy();
+ const testArg = 'testArgument';
+
+ testRenderer3.setRender(func1);
+ testRenderer3.render(testArg);
+ func1.calledWith(testArg).should.be.ok;
+ });
});
describe('3rd party renderer', function () {
diff --git a/test/spec/unit/core/adapterManager_spec.js b/test/spec/unit/core/adapterManager_spec.js
index 88beaa88a67..6e37da4e85f 100644
--- a/test/spec/unit/core/adapterManager_spec.js
+++ b/test/spec/unit/core/adapterManager_spec.js
@@ -1671,25 +1671,29 @@ describe('adapterManager tests', function () {
})
});
- it('should add nativeParams to adUnits after BEFORE_REQUEST_BIDS', () => {
- function beforeReqBids(adUnits) {
- adUnits.forEach(adUnit => {
- adUnit.mediaTypes.native = {
- type: 'image',
- }
- })
- }
- events.on(CONSTANTS.EVENTS.BEFORE_REQUEST_BIDS, beforeReqBids);
- adapterManager.makeBidRequests(
- adUnits,
- Date.now(),
- utils.getUniqueIdentifierStr(),
- function callback() {},
- []
- );
- events.off(CONSTANTS.EVENTS.BEFORE_REQUEST_BIDS, beforeReqBids);
- expect(adUnits.map((u) => u.nativeParams).some(i => i == null)).to.be.false;
- });
+ if (FEATURES.NATIVE) {
+ it('should add nativeParams to adUnits after BEFORE_REQUEST_BIDS', () => {
+ function beforeReqBids(adUnits) {
+ adUnits.forEach(adUnit => {
+ adUnit.mediaTypes.native = {
+ type: 'image',
+ }
+ })
+ }
+
+ events.on(CONSTANTS.EVENTS.BEFORE_REQUEST_BIDS, beforeReqBids);
+ adapterManager.makeBidRequests(
+ adUnits,
+ Date.now(),
+ utils.getUniqueIdentifierStr(),
+ function callback() {
+ },
+ []
+ );
+ events.off(CONSTANTS.EVENTS.BEFORE_REQUEST_BIDS, beforeReqBids);
+ expect(adUnits.map((u) => u.nativeParams).some(i => i == null)).to.be.false;
+ });
+ }
it('should make separate bidder request objects for each bidder', () => {
adUnits = [utils.deepClone(getAdUnits()[0])];
@@ -1711,6 +1715,83 @@ describe('adapterManager tests', function () {
expect(sizes1).not.to.deep.equal(sizes2);
});
+ it('should make FPD available under `ortb2`', () => {
+ const global = {
+ k1: 'v1',
+ k2: {
+ k3: 'v3',
+ k4: 'v4'
+ }
+ };
+ const bidder = {
+ 'appnexus': {
+ ka: 'va',
+ k2: {
+ k3: 'override',
+ k5: 'v5'
+ }
+ }
+ };
+ const requests = Object.fromEntries(
+ adapterManager.makeBidRequests(adUnits, 123, 'auction-id', 123, [], {global, bidder})
+ .map((r) => [r.bidderCode, r])
+ );
+ sinon.assert.match(requests, {
+ rubicon: {
+ ortb2: global
+ },
+ appnexus: {
+ ortb2: {
+ k1: 'v1',
+ ka: 'va',
+ k2: {
+ k3: 'override',
+ k4: 'v4',
+ k5: 'v5',
+ }
+ }
+ }
+ });
+ requests.rubicon.bids.forEach((bid) => expect(bid.ortb2).to.eql(requests.rubicon.ortb2));
+ requests.appnexus.bids.forEach((bid) => expect(bid.ortb2).to.eql(requests.appnexus.ortb2));
+ });
+
+ describe('when calling the s2s adapter', () => {
+ beforeEach(() => {
+ config.setConfig({
+ s2sConfig: {
+ enabled: true,
+ adapter: 'mockS2S',
+ bidders: ['appnexus']
+ }
+ })
+ adapterManager.bidderRegistry.mockS2S = {
+ callBids: sinon.stub()
+ };
+ });
+ afterEach(() => {
+ config.resetConfig();
+ delete adapterManager.bidderRegistry.mockS2S;
+ })
+
+ it('should pass FPD', () => {
+ const ortb2Fragments = {};
+ const req = {
+ bidderCode: 'appnexus',
+ src: CONSTANTS.S2S.SRC,
+ adUnitsS2SCopy: adUnits,
+ bids: [{
+ bidder: 'appnexus',
+ src: CONSTANTS.S2S.SRC
+ }]
+ };
+ adapterManager.callBids(adUnits, [req], sinon.stub(), sinon.stub(), {request: sinon.stub(), done: sinon.stub()}, 1000, sinon.stub(), ortb2Fragments);
+ sinon.assert.calledWith(adapterManager.bidderRegistry.mockS2S.callBids, sinon.match({
+ ortb2Fragments: sinon.match.same(ortb2Fragments)
+ }));
+ });
+ })
+
describe('setBidderSequence', function () {
beforeEach(function () {
sinon.spy(utils, 'shuffle');
@@ -1734,6 +1815,64 @@ describe('adapterManager tests', function () {
});
});
+ describe('fledgeEnabled', function () {
+ const origRunAdAuction = navigator?.runAdAuction;
+ before(function () {
+ // navigator.runAdAuction doesn't exist, so we can't stub it normally with
+ // sinon.stub(navigator, 'runAdAuction') or something
+ navigator.runAdAuction = sinon.stub();
+ });
+
+ after(function() {
+ navigator.runAdAuction = origRunAdAuction;
+ })
+
+ afterEach(function () {
+ config.resetConfig();
+ });
+
+ it('should set fledgeEnabled correctly per bidder', function () {
+ config.setConfig({bidderSequence: 'fixed'})
+ config.setBidderConfig({
+ bidders: ['appnexus'],
+ config: {
+ fledgeEnabled: true,
+ }
+ });
+
+ const adUnits = [{
+ 'code': '/19968336/header-bid-tag1',
+ 'mediaTypes': {
+ 'banner': {
+ 'sizes': [[728, 90]]
+ },
+ },
+ 'bids': [
+ {
+ 'bidder': 'appnexus',
+ },
+ {
+ 'bidder': 'rubicon',
+ },
+ ]
+ }];
+
+ const bidRequests = adapterManager.makeBidRequests(
+ adUnits,
+ Date.now(),
+ utils.getUniqueIdentifierStr(),
+ function callback() {},
+ []
+ );
+
+ expect(bidRequests[0].bids[0].bidder).equals('appnexus');
+ expect(bidRequests[0].fledgeEnabled).to.be.true;
+
+ expect(bidRequests[1].bids[0].bidder).equals('rubicon');
+ expect(bidRequests[1].fledgeEnabled).to.be.undefined;
+ });
+ });
+
describe('sizeMapping', function () {
let sandbox;
beforeEach(function () {
diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js
index 20a545a51d4..7164e468e71 100644
--- a/test/spec/unit/core/bidderFactory_spec.js
+++ b/test/spec/unit/core/bidderFactory_spec.js
@@ -12,6 +12,7 @@ import {hook} from '../../../../src/hook.js';
import {auctionManager} from '../../../../src/auctionManager.js';
import {stubAuctionIndex} from '../../../helpers/indexStub.js';
import { bidderSettings } from '../../../../src/bidderSettings.js';
+import {decorateAdUnitsWithNativeParams} from '../../../../src/native.js';
const CODE = 'sampleBidder';
const MOCK_BIDS_REQUEST = {
@@ -39,6 +40,10 @@ function onTimelyResponseStub() {
}
+before(() => {
+ hook.ready();
+});
+
let wrappedCallback = config.callbackWithBidder(CODE);
describe('bidders created by newBidder', function () {
@@ -47,10 +52,6 @@ describe('bidders created by newBidder', function () {
let addBidResponseStub;
let doneStub;
- before(() => {
- hook.ready();
- });
-
beforeEach(function () {
spec = {
code: CODE,
@@ -874,85 +875,89 @@ describe('validate bid response: ', function () {
indexStub.restore;
});
- it('should add native bids that do have required assets', function () {
- adUnits = [{
- transactionId: 'au',
- nativeParams: {
- title: {'required': true},
- }
- }]
- let bidRequest = {
- bids: [{
- bidId: '1',
- auctionId: 'first-bid-id',
- adUnitCode: 'mock/placement',
+ if (FEATURES.NATIVE) {
+ it('should add native bids that do have required assets', function () {
+ adUnits = [{
transactionId: 'au',
- params: {
- param: 5
- },
- mediaType: 'native',
+ nativeParams: {
+ title: {'required': true},
+ }
}]
- };
+ decorateAdUnitsWithNativeParams(adUnits);
+ let bidRequest = {
+ bids: [{
+ bidId: '1',
+ auctionId: 'first-bid-id',
+ adUnitCode: 'mock/placement',
+ transactionId: 'au',
+ params: {
+ param: 5
+ },
+ mediaType: 'native',
+ }]
+ };
- let bids1 = Object.assign({},
- bids[0],
- {
- 'mediaType': 'native',
- 'native': {
- 'title': 'Native Creative',
- 'clickUrl': 'https://www.link.example',
+ let bids1 = Object.assign({},
+ bids[0],
+ {
+ 'mediaType': 'native',
+ 'native': {
+ 'title': 'Native Creative',
+ 'clickUrl': 'https://www.link.example',
+ }
}
- }
- );
+ );
- const bidder = newBidder(spec);
+ const bidder = newBidder(spec);
- spec.interpretResponse.returns(bids1);
- bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
+ spec.interpretResponse.returns(bids1);
+ bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
- expect(addBidResponseStub.calledOnce).to.equal(true);
- expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement');
- expect(logErrorSpy.callCount).to.equal(0);
- });
+ expect(addBidResponseStub.calledOnce).to.equal(true);
+ expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement');
+ expect(logErrorSpy.callCount).to.equal(0);
+ });
- it('should not add native bids that do not have required assets', function () {
- adUnits = [{
- transactionId: 'au',
- nativeParams: {
- title: {'required': true},
- },
- }];
- let bidRequest = {
- bids: [{
- bidId: '1',
- auctionId: 'first-bid-id',
- adUnitCode: 'mock/placement',
+ it('should not add native bids that do not have required assets', function () {
+ adUnits = [{
transactionId: 'au',
- params: {
- param: 5
+ nativeParams: {
+ title: {'required': true},
},
- mediaType: 'native',
- }]
- };
- let bids1 = Object.assign({},
- bids[0],
- {
- bidderCode: CODE,
- mediaType: 'native',
- native: {
- title: undefined,
- clickUrl: 'https://www.link.example',
+ }];
+ decorateAdUnitsWithNativeParams(adUnits);
+ let bidRequest = {
+ bids: [{
+ bidId: '1',
+ auctionId: 'first-bid-id',
+ adUnitCode: 'mock/placement',
+ transactionId: 'au',
+ params: {
+ param: 5
+ },
+ mediaType: 'native',
+ }]
+ };
+ let bids1 = Object.assign({},
+ bids[0],
+ {
+ bidderCode: CODE,
+ mediaType: 'native',
+ native: {
+ title: undefined,
+ clickUrl: 'https://www.link.example',
+ }
}
- }
- );
+ );
- const bidder = newBidder(spec);
- spec.interpretResponse.returns(bids1);
- bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
+ const bidder = newBidder(spec);
+ spec.interpretResponse.returns(bids1);
+ bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
- expect(addBidResponseStub.calledOnce).to.equal(false);
- expect(logErrorSpy.callCount).to.equal(1);
- });
+ expect(addBidResponseStub.calledOnce).to.equal(false);
+ expect(logErrorSpy.calledWithMatch('Ignoring bid: Native bid missing some required properties.')).to.equal(true);
+ });
+ }
it('should add bid when renderer is present on outstream bids', function () {
adUnits = [{
@@ -1045,8 +1050,8 @@ describe('validate bid response: ', function () {
bids1 = Object.assign({},
bids[0],
{
- bidderCode: 'validAlternateBidder',
- adapterCode: 'knownAdapter1'
+ bidderCode: 'validalternatebidder',
+ adapterCode: 'knownadapter1'
}
);
logWarnSpy = sinon.spy(utils, 'logWarn');
@@ -1073,16 +1078,14 @@ describe('validate bid response: ', function () {
expect(logWarnSpy.callCount).to.equal(1);
});
- it('should accept the bid, when allowAlternateBidderCodes flag is undefined (default should be true)', function () {
+ it('should reject the bid, when allowAlternateBidderCodes flag is undefined (default should be false)', function () {
bidderSettingStub.returns(undefined);
const bidder = newBidder(spec);
spec.interpretResponse.returns(bids1);
bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
- expect(addBidResponseStub.calledOnce).to.equal(true);
- expect(logWarnSpy.callCount).to.equal(0);
- expect(logErrorSpy.callCount).to.equal(0);
+ expect(addBidResponseStub.calledOnce).to.equal(false);
});
it('should log warning when the particular bidder is not specified in allowedAlternateBidderCodes and allowAlternateBidderCodes flag is true', function () {
@@ -1123,6 +1126,31 @@ describe('validate bid response: ', function () {
expect(logErrorSpy.callCount).to.equal(0);
});
+ it('should accept the bid, when allowedAlternateBidderCodes is marked as * (with space) and allowAlternateBidderCodes flag is true', function () {
+ bidderSettingStub.withArgs(CODE, 'allowAlternateBidderCodes').returns(true);
+ bidderSettingStub.withArgs(CODE, 'allowedAlternateBidderCodes').returns([' * ']);
+
+ const bidder = newBidder(spec);
+ spec.interpretResponse.returns(bids1);
+ bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
+
+ expect(addBidResponseStub.calledOnce).to.equal(true);
+ expect(logWarnSpy.callCount).to.equal(0);
+ expect(logErrorSpy.callCount).to.equal(0);
+ });
+
+ it('should not accept the bid, when allowedAlternateBidderCodes is marked as empty array and allowAlternateBidderCodes flag is true', function () {
+ bidderSettingStub.withArgs(CODE, 'allowAlternateBidderCodes').returns(true);
+ bidderSettingStub.withArgs(CODE, 'allowedAlternateBidderCodes').returns([]);
+
+ const bidder = newBidder(spec);
+ spec.interpretResponse.returns(bids1);
+ bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
+
+ expect(addBidResponseStub.calledOnce).to.equal(false);
+ expect(logWarnSpy.callCount).to.equal(1);
+ });
+
it('should accept the bid, when allowedAlternateBidderCodes contains bidder name and allowAlternateBidderCodes flag is true', function () {
bidderSettingStub.withArgs(CODE, 'allowAlternateBidderCodes').returns(true);
bidderSettingStub.withArgs(CODE, 'allowedAlternateBidderCodes').returns(['validAlternateBidder']);
@@ -1158,6 +1186,70 @@ describe('validate bid response: ', function () {
expect(addBidResponseStub.calledOnce).to.equal(false);
expect(logWarnSpy.callCount).to.equal(1);
});
+ });
+
+ describe('when interpretResponse returns BidderAuctionResponse', function() {
+ const bidRequest = {
+ bids: [{
+ bidId: '1',
+ bidder: CODE,
+ auctionId: 'first-bid-id',
+ adUnitCode: 'mock/placement',
+ transactionId: 'au',
+ }]
+ };
+ const fledgeAuctionConfig = {
+ bidId: '1',
+ }
+ describe('when response has FLEDGE auction config', function() {
+ let logInfoSpy;
+
+ beforeEach(function () {
+ logInfoSpy = sinon.spy(utils, 'logInfo');
+ });
+
+ afterEach(function () {
+ logInfoSpy.restore();
+ });
+
+ it('should unwrap bids', function() {
+ const bidder = newBidder(spec);
+ spec.interpretResponse.returns({
+ bids: bids,
+ fledgeAuctionConfigs: []
+ });
+ bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
+ expect(addBidResponseStub.calledOnce).to.equal(true);
+ expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement');
+ });
+
+ it('should call fledgeManager with FLEDGE configs', function() {
+ const bidder = newBidder(spec);
+ spec.interpretResponse.returns({
+ bids: bids,
+ fledgeAuctionConfigs: [fledgeAuctionConfig]
+ });
+ bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
+
+ expect(logInfoSpy.calledOnce).to.equal(true);
+ expect(logInfoSpy.firstCall.args[1]).to.equal(fledgeAuctionConfig);
+ expect(addBidResponseStub.calledOnce).to.equal(true);
+ expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement');
+ })
+
+ it('should call fledgeManager with FLEDGE configs even if no bids returned', function() {
+ const bidder = newBidder(spec);
+ spec.interpretResponse.returns({
+ bids: [],
+ fledgeAuctionConfigs: [fledgeAuctionConfig]
+ });
+ bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback);
+
+ expect(logInfoSpy.calledOnce).to.equal(true);
+ expect(logInfoSpy.firstCall.args[1]).to.equal(fledgeAuctionConfig);
+ expect(addBidResponseStub.calledOnce).to.equal(false);
+ })
+ })
})
});
diff --git a/test/spec/unit/core/storageManager_spec.js b/test/spec/unit/core/storageManager_spec.js
index 74a3b3b023f..cb38aed9e47 100644
--- a/test/spec/unit/core/storageManager_spec.js
+++ b/test/spec/unit/core/storageManager_spec.js
@@ -3,7 +3,7 @@ import {
getCoreStorageManager,
storageCallbacks,
getStorageManager,
- newStorageManager
+ newStorageManager, validateStorageEnforcement
} from 'src/storageManager.js';
import { config } from 'src/config.js';
import * as utils from 'src/utils.js';
@@ -55,6 +55,33 @@ describe('storage manager', function() {
deviceAccessSpy.restore();
});
+ describe(`core storage`, () => {
+ let storage, validateHook;
+
+ beforeEach(() => {
+ storage = getCoreStorageManager();
+ validateHook = sinon.stub().callsFake(function (next, ...args) {
+ next.apply(this, args);
+ });
+ validateStorageEnforcement.before(validateHook, 99);
+ });
+
+ afterEach(() => {
+ validateStorageEnforcement.getHooks({hook: validateHook}).remove();
+ config.resetConfig();
+ })
+
+ it('should respect (vendorless) consent enforcement', () => {
+ storage.localStorageIsEnabled();
+ expect(validateHook.args[0][1]).to.eql(true); // isVendorless should be set to true
+ });
+
+ it('should respect the deviceAccess flag', () => {
+ config.setConfig({deviceAccess: false});
+ expect(storage.localStorageIsEnabled()).to.be.false
+ })
+ })
+
describe('localstorage forbidden access in 3rd-party context', function() {
let errorLogSpy;
let originalLocalStorage;
@@ -108,8 +135,8 @@ describe('storage manager', function() {
});
describe('when bidderSettings.allowStorage is defined', () => {
- const DENIED_BIDDER = 'denied-bidder';
- const DENY_KEY = 'storageAllowed';
+ const ALLOWED_BIDDER = 'allowed-bidder';
+ const ALLOW_KEY = 'storageAllowed';
const COOKIE = 'test-cookie';
const LS_KEY = 'test-localstorage';
@@ -117,8 +144,8 @@ describe('storage manager', function() {
function mockBidderSettings() {
return {
get(bidder, key) {
- if (bidder === DENIED_BIDDER && key === DENY_KEY) {
- return false;
+ if (bidder === ALLOWED_BIDDER && key === ALLOW_KEY) {
+ return true;
} else {
return undefined;
}
@@ -127,8 +154,8 @@ describe('storage manager', function() {
}
Object.entries({
- disallowed: [DENIED_BIDDER, false],
- allowed: ['allowed-bidder', true]
+ disallowed: ['denied_bidder', false],
+ allowed: [ALLOWED_BIDDER, true]
}).forEach(([test, [bidderCode, shouldWork]]) => {
describe(`for ${test} bidders`, () => {
let mgr;
diff --git a/test/spec/unit/core/targeting_spec.js b/test/spec/unit/core/targeting_spec.js
index 53aa3b90fa8..4585ddbfaaf 100644
--- a/test/spec/unit/core/targeting_spec.js
+++ b/test/spec/unit/core/targeting_spec.js
@@ -599,7 +599,9 @@ describe('targeting tests', function () {
}
});
const defaultKeys = new Set(Object.values(CONSTANTS.DEFAULT_TARGETING_KEYS));
- Object.values(CONSTANTS.NATIVE_KEYS).forEach((k) => defaultKeys.add(k));
+ if (FEATURES.NATIVE) {
+ Object.values(CONSTANTS.NATIVE_KEYS).forEach((k) => defaultKeys.add(k));
+ }
const expectedKeys = new Set();
bidsReceived
@@ -802,26 +804,28 @@ describe('targeting tests', function () {
expect(targeting['/123456/header-bid-tag-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_rubicon']).to.deep.equal(targeting['/123456/header-bid-tag-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]);
});
- it('ensures keys are properly generated when enableSendAllBids is true and multiple bidders use native', function() {
- const nativeAdUnitCode = '/19968336/prebid_native_example_1';
- enableSendAllBids = true;
+ if (FEATURES.NATIVE) {
+ it('ensures keys are properly generated when enableSendAllBids is true and multiple bidders use native', function () {
+ const nativeAdUnitCode = '/19968336/prebid_native_example_1';
+ enableSendAllBids = true;
- // update mocks for this test to return native bids
- amBidsReceivedStub.callsFake(function() {
- return [nativeBid1, nativeBid2];
- });
- amGetAdUnitsStub.callsFake(function() {
- return [nativeAdUnitCode];
- });
+ // update mocks for this test to return native bids
+ amBidsReceivedStub.callsFake(function () {
+ return [nativeBid1, nativeBid2];
+ });
+ amGetAdUnitsStub.callsFake(function () {
+ return [nativeAdUnitCode];
+ });
- let targeting = targetingInstance.getAllTargeting([nativeAdUnitCode]);
- expect(targeting[nativeAdUnitCode].hb_native_image).to.equal(nativeBid1.native.image.url);
- expect(targeting[nativeAdUnitCode].hb_native_linkurl).to.equal(nativeBid1.native.clickUrl);
- expect(targeting[nativeAdUnitCode].hb_native_title).to.equal(nativeBid1.native.title);
- expect(targeting[nativeAdUnitCode].hb_native_image_dgad).to.exist.and.to.equal(nativeBid2.native.image.url);
- expect(targeting[nativeAdUnitCode].hb_pb_dgads).to.exist.and.to.equal(nativeBid2.pbMg);
- expect(targeting[nativeAdUnitCode].hb_native_body_appne).to.exist.and.to.equal(nativeBid1.native.body);
- });
+ let targeting = targetingInstance.getAllTargeting([nativeAdUnitCode]);
+ expect(targeting[nativeAdUnitCode].hb_native_image).to.equal(nativeBid1.native.image.url);
+ expect(targeting[nativeAdUnitCode].hb_native_linkurl).to.equal(nativeBid1.native.clickUrl);
+ expect(targeting[nativeAdUnitCode].hb_native_title).to.equal(nativeBid1.native.title);
+ expect(targeting[nativeAdUnitCode].hb_native_image_dgad).to.exist.and.to.equal(nativeBid2.native.image.url);
+ expect(targeting[nativeAdUnitCode].hb_pb_dgads).to.exist.and.to.equal(nativeBid2.pbMg);
+ expect(targeting[nativeAdUnitCode].hb_native_body_appne).to.exist.and.to.equal(nativeBid1.native.body);
+ });
+ }
it('does not include adpod type bids in the getBidsReceived results', function () {
let adpodBid = utils.deepClone(bid1);
diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js
index 6a7c79fe49d..3cee2b6b679 100644
--- a/test/spec/unit/pbjs_api_spec.js
+++ b/test/spec/unit/pbjs_api_spec.js
@@ -16,9 +16,11 @@ import * as auctionModule from 'src/auction.js';
import { registerBidder } from 'src/adapters/bidderFactory.js';
import { _sendAdToCreative } from 'src/secureCreatives.js';
import {find} from 'src/polyfill.js';
-import {synchronizePromise} from '../../helpers/syncPromise.js';
-import 'src/prebid.js';
+import * as pbjsModule from 'src/prebid.js';
import {hook} from '../../../src/hook.js';
+import {reset as resetDebugging} from '../../../src/debugging.js';
+import $$PREBID_GLOBAL$$ from 'src/prebid.js';
+import {resetAuctionState} from 'src/auction.js';
var assert = require('chai').assert;
var expect = require('chai').expect;
@@ -33,7 +35,6 @@ require('modules/appnexusBidAdapter');
var config = require('test/fixtures/config.json');
-$$PREBID_GLOBAL$$ = $$PREBID_GLOBAL$$ || {};
var adUnits = getAdUnits();
var adUnitCodes = getAdUnits().map(unit => unit.code);
var bidsBackHandler = function() {};
@@ -193,22 +194,21 @@ window.apntag = {
}
describe('Unit: Prebid Module', function () {
- let bidExpiryStub, promiseSandbox;
+ let bidExpiryStub
before(() => {
hook.ready();
$$PREBID_GLOBAL$$.requestBids.getHooks().remove();
+ resetDebugging();
});
beforeEach(function () {
- promiseSandbox = sinon.createSandbox();
- synchronizePromise(promiseSandbox);
bidExpiryStub = sinon.stub(filters, 'isBidNotExpired').callsFake(() => true);
configObj.setConfig({ useBidCache: true });
+ resetAuctionState();
});
afterEach(function() {
- promiseSandbox.restore();
$$PREBID_GLOBAL$$.adUnits = [];
bidExpiryStub.restore();
configObj.setConfig({ useBidCache: false });
@@ -218,6 +218,51 @@ describe('Unit: Prebid Module', function () {
auctionManager.clearAllAuctions();
});
+ describe('and global adUnits', () => {
+ const startingAdUnits = [
+ {
+ code: 'one',
+ },
+ {
+ code: 'two',
+ }
+ ];
+ let actualAdUnits, hookRan, done;
+
+ function deferringHook(next, req) {
+ setTimeout(() => {
+ actualAdUnits = req.adUnits || $$PREBID_GLOBAL$$.adUnits;
+ done();
+ });
+ }
+
+ beforeEach(() => {
+ $$PREBID_GLOBAL$$.requestBids.before(deferringHook, 99);
+ $$PREBID_GLOBAL$$.adUnits.splice(0, $$PREBID_GLOBAL$$.adUnits.length, ...startingAdUnits);
+ hookRan = new Promise((resolve) => {
+ done = resolve;
+ });
+ });
+
+ afterEach(() => {
+ $$PREBID_GLOBAL$$.requestBids.getHooks({hook: deferringHook}).remove();
+ $$PREBID_GLOBAL$$.adUnits.splice(0, $$PREBID_GLOBAL$$.adUnits.length);
+ })
+
+ Object.entries({
+ 'addAdUnits': (g) => g.addAdUnits({code: 'three'}),
+ 'removeAdUnit': (g) => g.removeAdUnit('one')
+ }).forEach(([method, op]) => {
+ it(`once called, should not be affected by ${method}`, () => {
+ $$PREBID_GLOBAL$$.requestBids({});
+ op($$PREBID_GLOBAL$$);
+ return hookRan.then(() => {
+ expect(actualAdUnits).to.eql(startingAdUnits);
+ })
+ });
+ });
+ });
+
describe('getAdserverTargetingForAdUnitCodeStr', function () {
beforeEach(function () {
resetAuction();
@@ -1605,8 +1650,124 @@ describe('Unit: Prebid Module', function () {
assert.ok(spyExecuteCallback.calledOnce, 'callback executed when bidRequests is empty');
});
});
+
+ describe('starts auction', () => {
+ let startAuctionStub;
+ function saHook(fn, ...args) {
+ return startAuctionStub(...args);
+ }
+ beforeEach(() => {
+ startAuctionStub = sinon.stub();
+ pbjsModule.startAuction.before(saHook);
+ configObj.resetConfig();
+ });
+ afterEach(() => {
+ pbjsModule.startAuction.getHooks({hook: saHook}).remove();
+ })
+ after(() => {
+ configObj.resetConfig();
+ });
+
+ it('passing global and auction-level FPD as ortb2Fragments.global', () => {
+ configObj.setConfig({
+ ortb2: {
+ 'k1': 'v1',
+ 'k2': {
+ 'k3': 'v3',
+ 'k4': 'v4'
+ }
+ }
+ });
+ $$PREBID_GLOBAL$$.requestBids({
+ ortb2: {
+ 'k5': 'v5',
+ 'k2': {
+ 'k3': 'override',
+ 'k7': 'v7'
+ }
+ }
+ });
+ sinon.assert.calledWith(startAuctionStub, sinon.match({
+ ortb2Fragments: {
+ global: {
+ 'k1': 'v1',
+ 'k5': 'v5',
+ 'k2': {
+ 'k3': 'override',
+ 'k4': 'v4',
+ 'k7': 'v7'
+ }
+ }
+ }
+ }))
+ });
+ it('passing bidder-specific FPD as ortb2Fragments.bidder', () => {
+ configObj.setBidderConfig({
+ bidders: ['bidderA', 'bidderC'],
+ config: {
+ ortb2: {
+ k1: 'v1'
+ }
+ }
+ });
+ configObj.setBidderConfig({
+ bidders: ['bidderB'],
+ config: {
+ ortb2: {
+ k2: 'v2'
+ }
+ }
+ });
+ $$PREBID_GLOBAL$$.requestBids({});
+ sinon.assert.calledWith(startAuctionStub, sinon.match({
+ ortb2Fragments: {
+ bidder: {
+ bidderA: {
+ k1: 'v1'
+ },
+ bidderB: {
+ k2: 'v2'
+ },
+ bidderC: {
+ k1: 'v1'
+ }
+ }
+ }
+ }));
+ });
+ });
});
+ describe('startAuction', () => {
+ let sandbox, newAuctionStub;
+ beforeEach(() => {
+ sandbox = sinon.createSandbox();
+ newAuctionStub = sandbox.stub(auctionManager, 'createAuction').callsFake(() => ({
+ getAuctionId: () => 'mockAuctionId',
+ callBids: sinon.stub()
+ }));
+ });
+
+ afterEach(() => {
+ sandbox.restore();
+ });
+
+ it('passes ortb2 fragments to createAuction', () => {
+ const ortb2Fragments = {};
+ pbjsModule.startAuction({
+ adUnits: [{
+ code: 'au',
+ mediaTypes: {banner: {sizes: [[300, 250]]}},
+ bids: [{bidder: 'bd'}]
+ }],
+ ortb2Fragments
+ });
+ sinon.assert.calledWith(newAuctionStub, sinon.match({
+ ortb2Fragments: sinon.match.same(ortb2Fragments)
+ }));
+ });
+ })
+
describe('requestBids', function () {
var adUnitsBackup;
var auctionManagerStub;
@@ -1680,6 +1841,29 @@ describe('Unit: Prebid Module', function () {
.and.to.match(/[a-f0-9\-]{36}/i);
});
+ it('should always set ortb2.ext.tid same as transactionId in adUnits', function () {
+ $$PREBID_GLOBAL$$.requestBids({
+ adUnits: [
+ {
+ code: 'test1',
+ mediaTypes: { banner: { sizes: [] } },
+ bids: []
+ }, {
+ code: 'test2',
+ mediaTypes: { banner: { sizes: [] } },
+ bids: []
+ }
+ ]
+ });
+
+ expect(auctionArgs.adUnits[0]).to.have.property('transactionId');
+ expect(auctionArgs.adUnits[0]).to.have.property('ortb2Imp');
+ expect(auctionArgs.adUnits[0].transactionId).to.equal(auctionArgs.adUnits[0].ortb2Imp.ext.tid);
+ expect(auctionArgs.adUnits[1]).to.have.property('transactionId');
+ expect(auctionArgs.adUnits[1]).to.have.property('ortb2Imp');
+ expect(auctionArgs.adUnits[1].transactionId).to.equal(auctionArgs.adUnits[1].ortb2Imp.ext.tid);
+ });
+
it('should notify targeting of the latest auction for each adUnit', function () {
let latestStub = sinon.stub(targeting, 'setLatestAuctionForAdUnit');
let getAuctionStub = sinon.stub(auction, 'getAuctionId').returns(2);
@@ -1973,59 +2157,61 @@ describe('Unit: Prebid Module', function () {
expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist;
assert.ok(logErrorSpy.calledWith('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.'));
- let badNativeImgSize = [{
- code: 'testb4',
- bids: [],
- mediaTypes: {
- native: {
- image: {
- sizes: '300x250'
+ if (FEATURES.NATIVE) {
+ let badNativeImgSize = [{
+ code: 'testb4',
+ bids: [],
+ mediaTypes: {
+ native: {
+ image: {
+ sizes: '300x250'
+ }
}
}
- }
- }];
- $$PREBID_GLOBAL$$.requestBids({
- adUnits: badNativeImgSize
- });
- expect(auctionArgs.adUnits[0].mediaTypes.native.image.sizes).to.be.undefined;
- expect(auctionArgs.adUnits[0].mediaTypes.native.image).to.exist;
- assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.image.sizes field. Removing invalid mediaTypes.native.image.sizes property from request.'));
-
- let badNativeImgAspRat = [{
- code: 'testb5',
- bids: [],
- mediaTypes: {
- native: {
- image: {
- aspect_ratios: '300x250'
+ }];
+ $$PREBID_GLOBAL$$.requestBids({
+ adUnits: badNativeImgSize
+ });
+ expect(auctionArgs.adUnits[0].mediaTypes.native.image.sizes).to.be.undefined;
+ expect(auctionArgs.adUnits[0].mediaTypes.native.image).to.exist;
+ assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.image.sizes field. Removing invalid mediaTypes.native.image.sizes property from request.'));
+
+ let badNativeImgAspRat = [{
+ code: 'testb5',
+ bids: [],
+ mediaTypes: {
+ native: {
+ image: {
+ aspect_ratios: '300x250'
+ }
}
}
- }
- }];
- $$PREBID_GLOBAL$$.requestBids({
- adUnits: badNativeImgAspRat
- });
- expect(auctionArgs.adUnits[0].mediaTypes.native.image.aspect_ratios).to.be.undefined;
- expect(auctionArgs.adUnits[0].mediaTypes.native.image).to.exist;
- assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.image.aspect_ratios field. Removing invalid mediaTypes.native.image.aspect_ratios property from request.'));
-
- let badNativeIcon = [{
- code: 'testb6',
- bids: [],
- mediaTypes: {
- native: {
- icon: {
- sizes: '300x250'
+ }];
+ $$PREBID_GLOBAL$$.requestBids({
+ adUnits: badNativeImgAspRat
+ });
+ expect(auctionArgs.adUnits[0].mediaTypes.native.image.aspect_ratios).to.be.undefined;
+ expect(auctionArgs.adUnits[0].mediaTypes.native.image).to.exist;
+ assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.image.aspect_ratios field. Removing invalid mediaTypes.native.image.aspect_ratios property from request.'));
+
+ let badNativeIcon = [{
+ code: 'testb6',
+ bids: [],
+ mediaTypes: {
+ native: {
+ icon: {
+ sizes: '300x250'
+ }
}
}
- }
- }];
- $$PREBID_GLOBAL$$.requestBids({
- adUnits: badNativeIcon
- });
- expect(auctionArgs.adUnits[0].mediaTypes.native.icon.sizes).to.be.undefined;
- expect(auctionArgs.adUnits[0].mediaTypes.native.icon).to.exist;
- assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.icon.sizes field. Removing invalid mediaTypes.native.icon.sizes property from request.'));
+ }];
+ $$PREBID_GLOBAL$$.requestBids({
+ adUnits: badNativeIcon
+ });
+ expect(auctionArgs.adUnits[0].mediaTypes.native.icon.sizes).to.be.undefined;
+ expect(auctionArgs.adUnits[0].mediaTypes.native.icon).to.exist;
+ assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.icon.sizes field. Removing invalid mediaTypes.native.icon.sizes property from request.'));
+ }
});
it('should throw error message and remove adUnit if adUnit.bids is not defined correctly', function () {
@@ -2058,6 +2244,9 @@ describe('Unit: Prebid Module', function () {
});
describe('multiformat requests', function () {
+ if (!FEATURES.NATIVE) {
+ return;
+ }
let adUnits;
beforeEach(function () {
@@ -2109,6 +2298,9 @@ describe('Unit: Prebid Module', function () {
});
describe('part 2', function () {
+ if (!FEATURES.NATIVE) {
+ return;
+ }
let spyCallBids;
let createAuctionStub;
let adUnits;
@@ -2176,7 +2368,7 @@ describe('Unit: Prebid Module', function () {
it('splits native type to individual native assets', function () {
let adUnits = [{
code: 'adUnit-code',
- mediaTypes: { native: { type: 'image' } },
+ mediaTypes: {native: {type: 'image'}},
bids: [
{bidder: 'appnexus', params: {placementId: 'id'}}
]
@@ -2184,14 +2376,47 @@ describe('Unit: Prebid Module', function () {
$$PREBID_GLOBAL$$.requestBids({adUnits});
const spyArgs = adapterManager.callBids.getCall(0);
const nativeRequest = spyArgs.args[1][0].bids[0].nativeParams;
- expect(nativeRequest).to.deep.equal({
- image: {required: true},
- title: {required: true},
- sponsoredBy: {required: true},
- clickUrl: {required: true},
- body: {required: false},
- icon: {required: false},
- });
+ expect(nativeRequest.ortb.assets).to.deep.equal([
+ {
+ required: 1,
+ id: 1,
+ img: {
+ type: 3,
+ wmin: 100,
+ hmin: 100,
+ }
+ },
+ {
+ required: 1,
+ id: 2,
+ title: {
+ len: 140,
+ }
+ },
+ {
+ required: 1,
+ id: 3,
+ data: {
+ type: 1,
+ }
+ },
+ {
+ required: 0,
+ id: 4,
+ data: {
+ type: 2,
+ }
+ },
+ {
+ required: 0,
+ id: 5,
+ img: {
+ type: 1,
+ wmin: 20,
+ hmin: 20,
+ }
+ },
+ ]);
resetAuction();
});
});
diff --git a/test/spec/unit/secureCreatives_spec.js b/test/spec/unit/secureCreatives_spec.js
index e3dc21ffd92..7d5f9af35dd 100644
--- a/test/spec/unit/secureCreatives_spec.js
+++ b/test/spec/unit/secureCreatives_spec.js
@@ -1,7 +1,6 @@
import {
_sendAdToCreative, getReplier, receiveMessage
} from 'src/secureCreatives.js';
-import * as secureCreatives from 'src/secureCreatives.js';
import * as utils from 'src/utils.js';
import {getAdUnits, getBidRequests, getBidResponses} from 'test/fixtures/fixtures.js';
import {auctionManager} from 'src/auctionManager.js';
@@ -164,6 +163,7 @@ describe('secureCreatives', () => {
stubGetAllAssetsMessage.restore();
stubEmit.restore();
resetAuction();
+ adResponse.adId = bidId;
});
describe('Prebid Request', function() {
@@ -308,36 +308,11 @@ describe('secureCreatives', () => {
});
describe('Prebid Native', function() {
- it('Prebid native should render', function () {
- pushBidResponseToAuction({});
-
- const data = {
- adId: bidId,
- message: 'Prebid Native',
- action: 'allAssetRequest'
- };
-
- const ev = makeEvent({
- data: JSON.stringify(data),
- source: {
- postMessage: sinon.stub()
- },
- origin: 'any origin'
- });
-
- receiveMessage(ev);
-
- sinon.assert.neverCalledWith(spyLogWarn, warning);
- sinon.assert.calledOnce(stubGetAllAssetsMessage);
- sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
- sinon.assert.calledOnce(ev.source.postMessage);
- sinon.assert.notCalled(stubFireNativeTrackers);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
- sinon.assert.notCalled(spyAddWinningBid);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
- });
+ if (!FEATURES.NATIVE) {
+ return;
+ }
- it('Prebid native should allow stale rendering without config', function () {
+ it('Prebid native should render', function () {
pushBidResponseToAuction({});
const data = {
@@ -361,31 +336,17 @@ describe('secureCreatives', () => {
sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
sinon.assert.calledOnce(ev.source.postMessage);
sinon.assert.notCalled(stubFireNativeTrackers);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
- sinon.assert.notCalled(spyAddWinningBid);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
-
- resetHistories(ev.source.postMessage);
-
- receiveMessage(ev);
-
- sinon.assert.neverCalledWith(spyLogWarn, warning);
- sinon.assert.calledOnce(stubGetAllAssetsMessage);
- sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
- sinon.assert.calledOnce(ev.source.postMessage);
- sinon.assert.notCalled(stubFireNativeTrackers);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
- sinon.assert.notCalled(spyAddWinningBid);
+ sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
+ sinon.assert.calledOnce(spyAddWinningBid);
sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
});
- it('Prebid native should allow stale rendering with config', function () {
- configObj.setConfig({'auctionOptions': {'suppressStaleRender': true}});
-
- pushBidResponseToAuction({});
+ it('Prebid native should not fire BID_WON when receiveMessage is called more than once', () => {
+ let adId = 3;
+ pushBidResponseToAuction({ adId });
const data = {
- adId: bidId,
+ adId: adId,
message: 'Prebid Native',
action: 'allAssetRequest'
};
@@ -399,37 +360,18 @@ describe('secureCreatives', () => {
});
receiveMessage(ev);
-
- sinon.assert.neverCalledWith(spyLogWarn, warning);
- sinon.assert.calledOnce(stubGetAllAssetsMessage);
- sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
- sinon.assert.calledOnce(ev.source.postMessage);
- sinon.assert.notCalled(stubFireNativeTrackers);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
- sinon.assert.notCalled(spyAddWinningBid);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
-
- resetHistories(ev.source.postMessage);
+ sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
receiveMessage(ev);
-
- sinon.assert.neverCalledWith(spyLogWarn, warning);
- sinon.assert.calledOnce(stubGetAllAssetsMessage);
- sinon.assert.calledWith(stubGetAllAssetsMessage, data, adResponse);
- sinon.assert.calledOnce(ev.source.postMessage);
- sinon.assert.notCalled(stubFireNativeTrackers);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
- sinon.assert.notCalled(spyAddWinningBid);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.STALE_RENDER);
-
- configObj.setConfig({'auctionOptions': {}});
+ stubEmit.withArgs(CONSTANTS.EVENTS.BID_WON, adResponse).calledOnce;
});
it('Prebid native should fire trackers', function () {
- pushBidResponseToAuction({});
+ let adId = 2;
+ pushBidResponseToAuction({adId});
const data = {
- adId: bidId,
+ adId: adId,
message: 'Prebid Native',
action: 'click',
};
@@ -446,8 +388,8 @@ describe('secureCreatives', () => {
sinon.assert.neverCalledWith(spyLogWarn, warning);
sinon.assert.calledOnce(stubFireNativeTrackers);
- sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
- sinon.assert.notCalled(spyAddWinningBid);
+ sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
+ sinon.assert.calledOnce(spyAddWinningBid);
resetHistories(ev.source.postMessage);
@@ -457,8 +399,8 @@ describe('secureCreatives', () => {
sinon.assert.neverCalledWith(spyLogWarn, warning);
sinon.assert.calledOnce(stubFireNativeTrackers);
- sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.BID_WON, adResponse);
- sinon.assert.calledOnce(spyAddWinningBid);
+ sinon.assert.neverCalledWith(stubEmit, CONSTANTS.EVENTS.BID_WON);
+ sinon.assert.notCalled(spyAddWinningBid);
expect(adResponse).to.have.property('status', CONSTANTS.BID_STATUS.RENDERED);
});
diff --git a/test/spec/unit/utils/promise_spec.js b/test/spec/unit/utils/promise_spec.js
index ee2d55bf9a5..a931b8bc9c4 100644
--- a/test/spec/unit/utils/promise_spec.js
+++ b/test/spec/unit/utils/promise_spec.js
@@ -1,49 +1,294 @@
-import {promiseControls} from '../../../../src/utils/promise.js';
+import {GreedyPromise, defer} from '../../../../src/utils/promise.js';
-describe('promiseControls', () => {
- function lazyControls() {
- // NOTE: here we are testing that calling resolve / reject works correctly regardless of whether the
- // browser runs promise resolvers before / after returning control to the code; e.g. with the following:
- //
- // new Promise(() => console.log('1')); console.log('2')
- //
- // it seems that the browser will output '1', then '2' - but is it always guaranteed to do so?
- // it's not clear from MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise)
- // so here we make sure it works in both cases.
-
- return promiseControls({
- promiseFactory: (r) => ({
- then: function () {
- const p = new Promise(r);
- return p.then.apply(p, arguments);
+describe('GreedyPromise', () => {
+ it('throws when resolver is not a function', () => {
+ expect(() => new GreedyPromise()).to.throw();
+ })
+
+ Object.entries({
+ 'resolved': (use) => new GreedyPromise((resolve) => use(resolve)),
+ 'rejected': (use) => new GreedyPromise((_, reject) => use(reject))
+ }).forEach(([t, makePromise]) => {
+ it(`runs callbacks immediately when ${t}`, () => {
+ let cbRan = false;
+ const cb = () => { cbRan = true };
+ let resolver;
+ makePromise((fn) => { resolver = fn }).then(cb, cb);
+ resolver();
+ expect(cbRan).to.be.true;
+ })
+ });
+
+ describe('unhandled rejections', () => {
+ let unhandled, done, stop;
+
+ function reset(expectUnhandled) {
+ let pending = expectUnhandled;
+ let resolver;
+ unhandled.reset();
+ unhandled.callsFake(() => {
+ pending--;
+ if (pending === 0) {
+ resolver();
}
})
- })
- }
+ done = new Promise((resolve) => {
+ resolver = resolve;
+ stop = function () {
+ if (expectUnhandled === 0) {
+ resolve()
+ } else {
+ resolver = resolve;
+ }
+ }
+ })
+ }
+
+ before(() => {
+ unhandled = sinon.stub();
+ window.addEventListener('unhandledrejection', unhandled);
+ });
+
+ after(() => {
+ window.removeEventListener('unhandledrejection', unhandled);
+ });
+
+ function getUnhandledErrors() {
+ return unhandled.args.map((args) => args[0].reason);
+ }
+
+ Object.entries({
+ 'simple reject': [1, (P) => { P.reject('err'); stop() }],
+ 'caught reject': [0, (P) => P.reject('err').catch((e) => { stop(); return e })],
+ 'unhandled reject with finally': [1, (P) => P.reject('err').finally(() => 'finally')],
+ 'error handler that throws': [1, (P) => P.reject('err').catch((e) => { stop(); throw e })],
+ 'rejection handled later in the chain': [0, (P) => P.reject('err').then((v) => v).catch((e) => { stop(); return e })],
+ 'multiple errors in one chain': [1, (P) => P.reject('err').then((v) => v).catch((e) => e).then((v) => { stop(); return P.reject(v) })],
+ 'multiple errors in one chain, all handled': [0, (P) => P.reject('err').then((v) => v).catch((e) => e).then((v) => P.reject(v)).catch((e) => { stop(); return e })],
+ 'separate chains for rejection and handling': [1, (P) => {
+ const p = P.reject('err');
+ p.catch((e) => { stop(); return e; })
+ p.then((v) => v);
+ }],
+ 'separate rejections merged without handling': [2, (P) => {
+ const p1 = P.reject('err1');
+ const p2 = P.reject('err2');
+ p1.then(() => p2).finally(stop);
+ }],
+ 'separate rejections merged for handling': [0, (P) => {
+ const p1 = P.reject('err1');
+ const p2 = P.reject('err2');
+ P.all([p1, p2]).catch((e) => { stop(); return e });
+ }],
+ // eslint-disable-next-line no-throw-literal
+ 'exception in resolver': [1, (P) => new P(() => { stop(); throw 'err'; })],
+ // eslint-disable-next-line no-throw-literal
+ 'exception in resolver, caught': [0, (P) => new P(() => { throw 'err' }).catch((e) => { stop(); return e })],
+ 'errors from nested promises': [1, (P) => new P((resolve) => setTimeout(() => { resolve(P.reject('err')); stop(); }))],
+ 'errors from nested promises, caught': [0, (P) => new P((resolve) => setTimeout(() => resolve(P.reject('err')))).catch((e) => { stop(); return e })],
+ }).forEach(([t, [expectUnhandled, op]]) => {
+ describe(`on ${t}`, () => {
+ it('should match vanilla Promises', () => {
+ let vanillaUnhandled;
+ reset(expectUnhandled);
+ op(Promise);
+ return done.then(() => {
+ vanillaUnhandled = getUnhandledErrors();
+ reset(expectUnhandled);
+ op(GreedyPromise);
+ return done;
+ }).then(() => {
+ const actualUnhandled = getUnhandledErrors();
+ expect(actualUnhandled.length).to.eql(expectUnhandled);
+ expect(actualUnhandled).to.eql(vanillaUnhandled);
+ })
+ })
+ })
+ });
+ });
+
+ describe('idioms', () => {
+ let makePromise, pendingFailure, pendingSuccess;
+
+ Object.entries({
+ // eslint-disable-next-line no-throw-literal
+ 'resolver that throws': (P) => new P(() => { throw 'error' }),
+ 'resolver that resolves multiple times': (P) => new P((resolve) => { resolve('first'); resolve('second'); }),
+ 'resolver that rejects multiple times': (P) => new P((resolve, reject) => { reject('first'); reject('second') }),
+ 'resolver that resolves and rejects': (P) => new P((resolve, reject) => { reject('first'); resolve('second') }),
+ 'resolver that resolves with multiple arguments': (P) => new P((resolve) => resolve('one', 'two')),
+ 'resolver that rejects with multiple arguments': (P) => new P((resolve, reject) => reject('one', 'two')),
+ 'resolver that resolves to a promise': (P) => new P((resolve) => resolve(makePromise(P, 'val'))),
+ 'resolver that resolves to a promise that resolves to a promise': (P) => new P((resolve) => resolve(makePromise(P, makePromise(P, 'val')))),
+ 'resolver that resolves to a rejected promise': (P) => new P((resolve) => resolve(makePromise(P, 'err', true))),
+ 'simple .then': (P) => makePromise(P, 'value').then((v) => `${v} and then`),
+ 'chained .then': (P) => makePromise(P, 'value').then((v) => makePromise(P, `${v} and then`)),
+ '.then with error handler': (P) => makePromise(P, 'err', true).then(null, (e) => `${e} and then`),
+ '.then with chained error handler': (P) => makePromise(P, 'err', true).then(null, (e) => makePromise(P, `${e} and then`)),
+ '.then that throws': (P) => makePromise(P, 'value').then((v) => { throw v }),
+ '.then that throws in error handler': (P) => makePromise(P, 'err', true).then(null, (e) => { throw e }),
+ '.then with no args': (P) => makePromise(P, 'value').then(),
+ '.then that rejects': (P) => makePromise(P, 'value').then((v) => P.reject(v)),
+ '.then that rejects in error handler': (P) => makePromise(P, 'err', true).then(null, (err) => P.reject(err)),
+ '.then with no error handler on a rejection': (P) => makePromise(P, 'err', true).then((v) => `resolved ${v}`),
+ '.then with no success handler on a resolution': (P) => makePromise(P, 'value').then(null, (e) => `caught ${e}`),
+ 'simple .catch': (P) => makePromise(P, 'err', true).catch((err) => `caught ${err}`),
+ 'identity .catch': (P) => makePromise(P, 'err', true).catch((err) => err).then((v) => v),
+ '.catch that throws': (P) => makePromise(P, 'err', true).catch((err) => { throw err }),
+ 'chained .catch': (P) => makePromise(P, 'err', true).catch((err) => makePromise(P, err)),
+ 'chained .catch that rejects': (P) => makePromise(P, 'err', true).catch((err) => P.reject(`reject with ${err}`)),
+ 'simple .finally': (P) => {
+ let fval;
+ return makePromise(P, 'value')
+ .finally(() => fval = 'finally ran')
+ .then((val) => `${val} ${fval}`)
+ },
+ 'chained .finally': (P) => {
+ let fval;
+ return makePromise(P, 'value')
+ .finally(() => pendingSuccess.then(() => { fval = 'finally ran' }))
+ .then((val) => `${val} ${fval}`)
+ },
+ '.finally on a rejection': (P) => {
+ let fval;
+ return makePromise(P, 'error', true)
+ .finally(() => { fval = 'finally' })
+ .catch((err) => `${err} ${fval}`)
+ },
+ 'chained .finally on a rejection': (P) => {
+ let fval;
+ return makePromise(P, 'error', true)
+ .finally(() => pendingSuccess.then(() => { fval = 'finally' }))
+ .catch((err) => `${err} ${fval}`)
+ },
+ // eslint-disable-next-line no-throw-literal
+ '.finally that throws': (P) => makePromise(P, 'value').finally(() => { throw 'error' }),
+ 'chained .finally that rejects': (P) => makePromise(P, 'value').finally(() => P.reject('error')),
+ 'scalar Promise.resolve': (P) => P.resolve('scalar'),
+ 'null Promise.resolve': (P) => P.resolve(null),
+ 'chained Promise.resolve': (P) => P.resolve(pendingSuccess),
+ 'chained Promise.resolve on failure': (P) => P.resolve(pendingFailure),
+ 'scalar Promise.reject': (P) => P.reject('scalar'),
+ 'chained Promise.reject': (P) => P.reject(pendingSuccess),
+ 'chained Promise.reject on failure': (P) => P.reject(pendingFailure),
+ 'simple Promise.all': (P) => P.all([makePromise(P, 'one'), makePromise(P, 'two')]),
+ 'Promise.all with scalars': (P) => P.all([makePromise(P, 'one'), 'two']),
+ 'Promise.all with errors': (P) => P.all([makePromise(P, 'one'), makePromise(P, 'two'), makePromise(P, 'err', true)]),
+ 'Promise.allSettled': (P) => P.allSettled([makePromise(P, 'one', true), makePromise(P, 'two'), makePromise(P, 'three', true)]),
+ 'Promise.allSettled with scalars': (P) => P.allSettled([makePromise(P, 'value'), 'scalar']),
+ 'Promise.race that succeeds': (P) => P.race([makePromise(P, 'error', true, 10), makePromise(P, 'success')]),
+ 'Promise.race that fails': (P) => P.race([makePromise(P, 'success', false, 10), makePromise(P, 'error', true)]),
+ 'Promise.race with scalars': (P) => P.race(['scalar', makePromise(P, 'success')]),
+ }).forEach(([t, op]) => {
+ describe(t, () => {
+ describe('when mixed with deferrals', () => {
+ beforeEach(() => {
+ makePromise = function(ctor, value, fail = false, delay = 0) {
+ // eslint-disable-next-line new-cap
+ return new ctor((resolve, reject) => {
+ setTimeout(() => fail ? reject(value) : resolve(value), delay)
+ })
+ };
+ pendingSuccess = makePromise(Promise, 'pending result', false, 10);
+ pendingFailure = makePromise(Promise, 'pending failure', true, 10);
+ });
+
+ it(`behaves like vanilla promises`, () => {
+ const vanilla = op(Promise);
+ const greedy = op(GreedyPromise);
+ // note that we are not using `allSettled` & co to resolve our promises,
+ // to avoid transformations those methods do under the hood
+ const {actual = {}, expected = {}} = {};
+ return new Promise((resolve) => {
+ let pending = 2;
+ function collect(dest, slot) {
+ return function (value) {
+ dest[slot] = value;
+ pending--;
+ if (pending === 0) {
+ resolve()
+ }
+ }
+ }
+ vanilla.then(collect(expected, 'success'), collect(expected, 'failure'));
+ greedy.then(collect(actual, 'success'), collect(actual, 'failure'));
+ }).then(() => {
+ expect(actual).to.eql(expected);
+ });
+ });
+
+ it(`once resolved, runs callbacks immediately`, () => {
+ const promise = op(GreedyPromise).catch(() => null);
+ return promise.then(() => {
+ let cbRan = false;
+ promise.then(() => { cbRan = true });
+ expect(cbRan).to.be.true;
+ });
+ });
+ });
+
+ describe('when all promises involved are greedy', () => {
+ beforeEach(() => {
+ makePromise = function(ctor, value, fail = false, delay = 0) {
+ // eslint-disable-next-line new-cap
+ return new ctor((resolve, reject) => {
+ const run = () => fail ? reject(value) : resolve(value);
+ delay === 0 ? run() : setTimeout(run, delay);
+ })
+ };
+ pendingSuccess = makePromise(GreedyPromise, 'pending result');
+ pendingFailure = makePromise(GreedyPromise, 'pending failure', true);
+ });
+
+ it('resolves immediately', () => {
+ let cbRan = false;
+ op(GreedyPromise).catch(() => null).then(() => { cbRan = true });
+ expect(cbRan).to.be.true;
+ });
+ });
+ });
+ });
+ });
+
+ describe('.timeout', () => {
+ const timeout = GreedyPromise.timeout;
+
+ it('should resolve immediately when ms is 0', () => {
+ let cbRan = false;
+ timeout(0.0).then(() => { cbRan = true });
+ expect(cbRan).to.be.true;
+ });
+
+ it('should schedule timeout on ms > 0', (done) => {
+ let cbRan = false;
+ timeout(5).then(() => { cbRan = true });
+ expect(cbRan).to.be.false;
+ setTimeout(() => {
+ expect(cbRan).to.be.true;
+ done();
+ }, 10)
+ });
+ });
+});
+
+describe('promiseControls', () => {
Object.entries({
'resolve': (p) => p,
'reject': (p) => p.then(() => 'wrong', (v) => v)
}).forEach(([method, transform]) => {
describe(method, () => {
- Object.entries({
- 'before the resolver': lazyControls,
- 'after the resolver': promiseControls,
- }).forEach(([t, controls]) => {
- describe(`when called ${t}`, () => {
- it(`should ${method} the promise`, () => {
- const ctl = controls();
- ctl[method]('result');
- return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
- });
+ it(`should ${method} the promise`, () => {
+ const ctl = defer();
+ ctl[method]('result');
+ return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
+ });
- it('should ignore calls after the first', () => {
- const ctl = controls();
- ctl[method]('result');
- ctl[method]('other');
- return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
- });
- })
- })
- })
+ it('should ignore calls after the first', () => {
+ const ctl = defer();
+ ctl[method]('result');
+ ctl[method]('other');
+ return transform(ctl.promise).then((res) => expect(res).to.equal('result'));
+ });
+ });
});
});
diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js
index 50a95b079c9..500f479355d 100644
--- a/test/spec/utils_spec.js
+++ b/test/spec/utils_spec.js
@@ -1243,4 +1243,20 @@ describe('Utils', function () {
});
});
});
+
+ describe('setScriptAttributes', () => {
+ it('correctly adds attributes from an object', () => {
+ const script = document.createElement('script'),
+ attrs = {
+ 'data-first_prop': '1',
+ 'data-second_prop': 'b',
+ 'id': 'newId'
+ };
+ script.id = 'oldId';
+ utils.setScriptAttributes(script, attrs);
+ expect(script.dataset['first_prop']).to.equal('1');
+ expect(script.dataset.second_prop).to.equal('b');
+ expect(script.id).to.equal('newId');
+ });
+ });
});
diff --git a/test/spec/videoCache_spec.js b/test/spec/videoCache_spec.js
index 34e9bed04b6..a13028c966a 100644
--- a/test/spec/videoCache_spec.js
+++ b/test/spec/videoCache_spec.js
@@ -4,6 +4,7 @@ import { config } from 'src/config.js';
import { server } from 'test/mocks/xhr.js';
import {auctionManager} from '../../src/auctionManager.js';
import {AuctionIndex} from '../../src/auctionIndex.js';
+import { batchingCache } from '../../src/auction.js';
const should = chai.should();
@@ -29,8 +30,7 @@ function getMockBid(bidder, auctionId, bidderRequestId) {
'sizes': [300, 250],
'bidId': '123',
'bidderRequestId': bidderRequestId,
- 'auctionId': auctionId,
- 'storedAuctionResponse': 11111
+ 'auctionId': auctionId
};
}
@@ -156,12 +156,12 @@ describe('The video cache', function () {
puts: [{
type: 'xml',
value: vastXml1,
- ttlseconds: 25,
+ ttlseconds: 40,
key: customKey1
}, {
type: 'xml',
value: vastXml2,
- ttlseconds: 25,
+ ttlseconds: 40,
key: customKey2
}]
};
@@ -206,7 +206,7 @@ describe('The video cache', function () {
puts: [{
type: 'xml',
value: vastXml1,
- ttlseconds: 25,
+ ttlseconds: 40,
key: customKey1,
bidid: '12345abc',
aid: '1234-56789-abcde',
@@ -214,7 +214,7 @@ describe('The video cache', function () {
}, {
type: 'xml',
value: vastXml2,
- ttlseconds: 25,
+ ttlseconds: 40,
key: customKey2,
bidid: 'cba54321',
aid: '1234-56789-abcde',
@@ -277,7 +277,7 @@ describe('The video cache', function () {
puts: [{
type: 'xml',
value: vastXml1,
- ttlseconds: 25,
+ ttlseconds: 40,
key: customKey1,
bidid: '12345abc',
bidder: 'appnexus',
@@ -286,7 +286,7 @@ describe('The video cache', function () {
}, {
type: 'xml',
value: vastXml2,
- ttlseconds: 25,
+ ttlseconds: 40,
key: customKey2,
bidid: 'cba54321',
bidder: 'rubicon',
@@ -298,6 +298,35 @@ describe('The video cache', function () {
JSON.parse(request.requestBody).should.deep.equal(payload);
});
+ it('should wait the duration of the batchTimeout and pass the correct batchSize if batched requests are enabled in the config', () => {
+ const mockAfterBidAdded = function() {};
+ let callback = null;
+ let mockTimeout = sinon.stub().callsFake((cb) => { callback = cb });
+
+ config.setConfig({
+ cache: {
+ url: 'https://prebid.adnxs.com/pbc/v1/cache',
+ batchSize: 3,
+ batchTimeout: 20
+ }
+ });
+
+ let stubCache = sinon.stub();
+ const batchAndStore = batchingCache(mockTimeout, stubCache);
+ for (let i = 0; i < 3; i++) {
+ batchAndStore({}, {}, mockAfterBidAdded);
+ }
+
+ sinon.assert.calledOnce(mockTimeout);
+ sinon.assert.calledWith(mockTimeout, sinon.match.any, 20);
+
+ const expectedBatch = [{ afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }, { afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }, { afterBidAdded: mockAfterBidAdded, auctionInstance: { }, bidResponse: { } }];
+
+ callback();
+
+ sinon.assert.calledWith(stubCache, expectedBatch);
+ });
+
function assertRequestMade(bid, expectedValue) {
store([bid], function () { });
@@ -310,7 +339,7 @@ describe('The video cache', function () {
puts: [{
type: 'xml',
value: expectedValue,
- ttlseconds: 25
+ ttlseconds: 40
}],
});
}
diff --git a/test/test_deps.js b/test/test_deps.js
index 77fbad93e1c..35713106f8c 100644
--- a/test/test_deps.js
+++ b/test/test_deps.js
@@ -4,6 +4,7 @@ window.process = {
}
};
+require('test/helpers/consentData.js');
require('test/helpers/prebidGlobal.js');
require('test/mocks/adloaderStub.js');
require('test/mocks/xhr.js');
diff --git a/webpack.conf.js b/webpack.conf.js
index 5269f5300f5..0ead550e446 100644
--- a/webpack.conf.js
+++ b/webpack.conf.js
@@ -1,12 +1,34 @@
+const TerserPlugin = require('terser-webpack-plugin');
var prebid = require('./package.json');
var path = require('path');
var webpack = require('webpack');
var helpers = require('./gulpHelpers.js');
var { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
var argv = require('yargs').argv;
+const fs = require('fs');
+const babelConfig = require('./babelConfig.js')({disableFeatures: helpers.getDisabledFeatures(), prebidDistUrlBase: argv.distUrlBase});
+const {WebpackManifestPlugin} = require('webpack-manifest-plugin')
var plugins = [
- new webpack.EnvironmentPlugin({'LiveConnectMode': null})
+ new webpack.EnvironmentPlugin({'LiveConnectMode': null}),
+ new WebpackManifestPlugin({
+ fileName: 'dependencies.json',
+ generate: (seed, files) => {
+ const entries = new Set();
+ const addEntry = entries.add.bind(entries);
+
+ files.forEach(file => file.chunk && file.chunk._groups && file.chunk._groups.forEach(addEntry));
+
+ return Array.from(entries).reduce((acc, entry) => {
+ const name = (entry.options || {}).name || (entry.runtimeChunk || {}).name
+ const files = (entry.chunks || [])
+ .filter(chunk => chunk.name !== name)
+ .flatMap(chunk => [...chunk.files])
+ .filter(Boolean);
+ return name && files.length ? {...acc, [`${name}.js`]: files} : acc
+ }, seed)
+ }
+ })
];
if (argv.analyze) {
@@ -28,15 +50,21 @@ module.exports = {
const entry = {
'prebid-core': {
import: './src/prebid.js'
+ },
+ 'debugging-standalone': {
+ import: './modules/debugging/standalone.js'
}
};
const selectedModules = new Set(helpers.getArgModules());
+
Object.entries(helpers.getModules()).forEach(([fn, mod]) => {
if (selectedModules.size === 0 || selectedModules.has(mod)) {
- entry[mod] = {
+ const moduleEntry = {
import: fn,
dependOn: 'prebid-core'
- }
+ };
+
+ entry[mod] = moduleEntry;
}
});
return entry;
@@ -53,7 +81,7 @@ module.exports = {
use: [
{
loader: 'babel-loader',
- options: helpers.getAnalyticsOptions(),
+ options: Object.assign({}, babelConfig, helpers.getAnalyticsOptions()),
}
]
},
@@ -63,6 +91,7 @@ module.exports = {
use: [
{
loader: 'babel-loader',
+ options: babelConfig
}
],
}
@@ -71,6 +100,40 @@ module.exports = {
optimization: {
usedExports: true,
sideEffects: true,
+ minimizer: [
+ new TerserPlugin({
+ extractComments: false, // do not generate unhelpful LICENSE comment
+ terserOptions: {
+ module: true, // do not prepend every module with 'use strict'; allow mangling of top-level locals
+ }
+ })
+ ],
+ splitChunks: {
+ chunks: 'initial',
+ minChunks: 1,
+ minSize: 0,
+ cacheGroups: (() => {
+ const libRoot = path.resolve(__dirname, 'libraries');
+ const libraries = Object.fromEntries(
+ fs.readdirSync(libRoot)
+ .filter((f) => fs.lstatSync(path.resolve(libRoot, f)).isDirectory())
+ .map(lib => {
+ const dir = path.resolve(libRoot, lib)
+ const def = {
+ name: lib,
+ test: (module) => {
+ return module.resource && module.resource.startsWith(dir)
+ }
+ }
+ return [lib, def];
+ })
+ );
+ return Object.assign(libraries, {
+ default: false,
+ defaultVendors: false
+ })
+ })()
+ }
},
plugins
};