diff --git a/modules/bidglassBidAdapter.js b/modules/bidglassBidAdapter.js
index c0b5bddd5f7..43762162ace 100644
--- a/modules/bidglassBidAdapter.js
+++ b/modules/bidglassBidAdapter.js
@@ -5,7 +5,7 @@ import {registerBidder} from '../src/adapters/bidderFactory.js';
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
* @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid
* @typedef {import('../src/adapters/bidderFactory.js').BidderRequest} BidderRequest
- * @typedef {import('../src/adapters/bidderFactory.js').validBidRequests} validBidRequests
+ * @typedef {import('../src/adapters/bidderFactory.js').ServerRequest} ServerRequest
* @typedef {import('../src/adapters/bidderFactory.js').ServerResponse} ServerResponse
*/
@@ -26,9 +26,9 @@ export const spec = {
/**
* Make a server request from the list of BidRequests.
*
- * @param {validBidRequests} validBidRequests an array of bids
+ * @param {BidRequest[]} validBidRequests an array of bids
* @param {BidderRequest} bidderRequest request by bidder
- * @return ServerRequest Info describing the request to the server.
+ * @return {ServerRequest} Info describing the request to the server.
*/
buildRequests: function(validBidRequests, bidderRequest) {
/*
@@ -102,12 +102,31 @@ export const spec = {
});
});
- // Stuff to send: page URL
+ // Consent data
+ const gdprConsentObj = bidderRequest && bidderRequest.gdprConsent;
+ const gppConsentObj = bidderRequest && bidderRequest.gppConsent;
+ const gppApplicableSections = gppConsentObj && gppConsentObj.applicableSections;
+ const ortb2Regs = bidderRequest && bidderRequest.ortb2 && bidderRequest.ortb2.regs;
+ const ortb2Gpp = ortb2Regs && ortb2Regs.gpp;
+
+ // Build bid request data to be sent to ad server
const bidReq = {
reqId: getUniqueIdentifierStr(),
imps: imps,
ref: getReferer(),
- ori: getOrigins()
+ ori: getOrigins(),
+
+ // GDPR applies? numeric boolean
+ gdprApplies: (gdprConsentObj && gdprConsentObj.gdprApplies) ? 1 : '',
+ // IAB TCF consent string
+ gdprConsent: (gdprConsentObj && gdprConsentObj.consentString) || '',
+
+ // IAB GPP consent string
+ gppString: (gppConsentObj && gppConsentObj.gppString) || ortb2Gpp || '',
+ // GPP Applicable Section IDs
+ gppSid: (isArray(gppApplicableSections) && gppApplicableSections.length)
+ ? gppApplicableSections.join(',')
+ : ((ortb2Gpp && ortb2Regs.gpp_sid) || '')
};
let url = 'https://bid.glass/ad/hb.php?' +
@@ -128,10 +147,12 @@ export const spec = {
* Unpack the response from the server into a list of bids.
*
* @param {ServerResponse} serverResponse A successful response from the server.
+ * @param {ServerRequest} serverRequest The original server request for this bid
* @return {Bid[]} An array of bids which were nested inside the server.
*/
- interpretResponse: function(serverResponse) {
+ interpretResponse: function(serverResponse, serverRequest) {
const bidResponses = [];
+ const bidReq = JSON.parse(serverRequest.data);
_each(serverResponse.body.bidResponses, function(serverBid) {
const bidResponse = {
@@ -145,7 +166,19 @@ export const spec = {
mediaType: serverBid.mediaType || 'banner',
netRevenue: true,
ttl: serverBid.ttl || 10,
- ad: serverBid.ad,
+ // Replace the &replaceme placeholder in the returned ',
'cpm': '0.01',
'creativeId': '-1',
'width': '300',
@@ -86,14 +95,14 @@ describe('Bid Glass Adapter', function () {
'mediaType': 'banner',
'netRevenue': true,
'ttl': 10,
- 'ad': '',
+ 'ad': '',
'meta': {
'advertiserDomains': ['https://example.com']
}
}];
- let result = spec.interpretResponse(response);
- expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0]));
+ let result = spec.interpretResponse(serverResponse, serverRequest);
+ expect(result[0]).to.deep.equal(expectedResponse[0]);
});
it('handles empty bid response', function () {
@@ -102,7 +111,7 @@ describe('Bid Glass Adapter', function () {
'bidResponses': []
}
};
- let result = spec.interpretResponse(response);
+ let result = spec.interpretResponse(response, serverRequest);
expect(result.length).to.equal(0);
});
});
diff --git a/test/spec/modules/conversantAnalyticsAdapter_spec.js b/test/spec/modules/conversantAnalyticsAdapter_spec.js
deleted file mode 100644
index f46de31b19c..00000000000
--- a/test/spec/modules/conversantAnalyticsAdapter_spec.js
+++ /dev/null
@@ -1,1113 +0,0 @@
-import sinon from 'sinon';
-import { expect } from 'chai';
-import { default as conversantAnalytics, CNVR_CONSTANTS, cnvrHelper } from 'modules/conversantAnalyticsAdapter';
-import * as utils from 'src/utils.js';
-import * as prebidGlobal from 'src/prebidGlobal';
-import { server } from '../../mocks/xhr.js';
-
-import {EVENTS} from 'src/constants.js'
-
-const events = require('src/events');
-
-describe('Conversant analytics adapter tests', function() {
- let sandbox; // sinon sandbox to make restoring all stubbed objects easier
- let clock; // clock stub from sinon to mock our cache cleanup interval
- let logInfoStub;
-
- const PREBID_VERSION = '$prebid.version$';
- const SITE_ID = 108060;
-
- let requests;
- const DATESTAMP = Date.now();
-
- const VALID_CONFIGURATION = {
- options: {
- site_id: SITE_ID,
- send_error_data: true
- }
- };
-
- const VALID_ALWAYS_SAMPLE_CONFIG = {
- options: {
- site_id: SITE_ID,
- cnvr_sampling: 1,
- send_error_data: true
- }
- };
-
- beforeEach(function () {
- requests = server.requests;
- sandbox = sinon.sandbox.create();
- sandbox.stub(events, 'getEvents').returns([]); // need to stub this otherwise unwanted events seem to get fired during testing
- const getGlobalStub = {
- version: PREBID_VERSION,
- getUserIds: function() { // userIdTargeting.js init() gets called on AUCTION_END so we need to mock this function.
- return {};
- }
- };
- sandbox.stub(prebidGlobal, 'getGlobal').returns(getGlobalStub); // getGlobal does not seem to be available in testing so need to mock it
- clock = sandbox.useFakeTimers(DATESTAMP); // to use sinon fake timers they MUST be created before the interval/timeout is created in the code you are testing.
-
- logInfoStub = sandbox.stub(utils, 'logInfo');/* .callsFake((arg, arg1, arg2) => { //debugging stuff
- console.log(arg);
- if (arg1) console.log(arg1);
- if (arg2) console.log(arg2);
- }); */
-
- conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
- });
-
- afterEach(function () {
- sandbox.restore();
- conversantAnalytics.disableAnalytics();
- });
-
- describe('Initialization Tests', function() {
- it('should log error if site id is not passed', function() {
- sandbox.stub(utils, 'logError');
- conversantAnalytics.disableAnalytics();
- conversantAnalytics.enableAnalytics();
- expect(utils.logError.calledWith(CNVR_CONSTANTS.LOG_PREFIX + 'siteId is required.')).to.be.true;
- });
-
- it('should not log error if valid config is passed', function() {
- sandbox.stub(utils, 'logError');
-
- conversantAnalytics.enableAnalytics(VALID_CONFIGURATION);
- expect(utils.logError.called).to.equal(false);
- expect(utils.logInfo.called).to.equal(true);
- expect(
- utils.logInfo.calledWith(
- CNVR_CONSTANTS.LOG_PREFIX + 'Conversant sample rate set to ' + CNVR_CONSTANTS.DEFAULT_SAMPLE_RATE
- )
- ).to.be.true;
- expect(
- utils.logInfo.calledWith(
- CNVR_CONSTANTS.LOG_PREFIX + 'Global sample rate set to 1'
- )
- ).to.be.true;
- });
-
- it('should sample when sampling set to 1', function() {
- sandbox.stub(utils, 'logError');
- conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
- expect(utils.logError.called).to.equal(false);
- expect(cnvrHelper.doSample).to.equal(true);
- });
-
- it('should NOT sample when sampling set to 0', function() {
- sandbox.stub(utils, 'logError');
- const NEVER_SAMPLE_CONFIG = utils.deepClone(VALID_ALWAYS_SAMPLE_CONFIG);
- NEVER_SAMPLE_CONFIG.options.cnvr_sampling = 0;
- conversantAnalytics.disableAnalytics();
- conversantAnalytics.enableAnalytics(NEVER_SAMPLE_CONFIG);
- expect(utils.logError.called).to.equal(false);
- expect(cnvrHelper.doSample).to.equal(false);
- });
- });
-
- describe('Helper Function Tests', function() {
- it('should cleanup up cache objects', function() {
- conversantAnalytics.enableAnalytics(VALID_CONFIGURATION);
-
- cnvrHelper.adIdLookup.keep = { timeReceived: DATESTAMP + 1 };
- cnvrHelper.adIdLookup.delete = { timeReceived: DATESTAMP - CNVR_CONSTANTS.MAX_MILLISECONDS_IN_CACHE };
-
- cnvrHelper.timeoutCache.keep = { timeReceived: DATESTAMP + 1 };
- cnvrHelper.timeoutCache.delete = { timeReceived: DATESTAMP - CNVR_CONSTANTS.MAX_MILLISECONDS_IN_CACHE };
-
- cnvrHelper.auctionIdTimestampCache.keep = { timeReceived: DATESTAMP + 1 };
- cnvrHelper.auctionIdTimestampCache.delete = { timeReceived: DATESTAMP - CNVR_CONSTANTS.MAX_MILLISECONDS_IN_CACHE };
-
- cnvrHelper.bidderErrorCache.keep = { timeReceived: DATESTAMP + 1, errors: [] };
- cnvrHelper.bidderErrorCache.delete = { timeReceived: DATESTAMP - CNVR_CONSTANTS.MAX_MILLISECONDS_IN_CACHE, errors: [] };
-
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(2);
- expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(2);
- expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(2);
- expect(Object.keys(cnvrHelper.bidderErrorCache)).to.have.lengthOf(2);
-
- clock.tick(CNVR_CONSTANTS.CACHE_CLEANUP_TIME_IN_MILLIS);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
- expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(1);
- expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(1);
- expect(Object.keys(cnvrHelper.bidderErrorCache)).to.have.lengthOf(1);
-
- conversantAnalytics.disableAnalytics();
-
- // After disable we should cleanup the cache
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.bidderErrorCache)).to.have.lengthOf(0);
- });
-
- it('createBid() should return correct object', function() {
- const EVENT_CODE = 1;
- const TIME = 2;
- const bid = cnvrHelper.createBid(EVENT_CODE, 2);
- expect(bid).to.deep.equal({ eventCodes: [EVENT_CODE], timeToRespond: TIME });
- });
-
- it('createAdUnit() should return correct object', function() {
- const adUnit = cnvrHelper.createAdUnit();
- expect(adUnit).to.deep.equal({
- sizes: [],
- mediaTypes: [],
- bids: {}
- });
- });
-
- it('createAdSize() should return correct object', function() {
- let adSize = cnvrHelper.createAdSize(1, 2);
- expect(adSize).to.deep.equal({ w: 1, h: 2 });
-
- adSize = cnvrHelper.createAdSize();
- expect(adSize).to.deep.equal({ w: -1, h: -1 });
-
- adSize = cnvrHelper.createAdSize('foo', 'bar');
- expect(adSize).to.deep.equal({ w: -1, h: -1 });
- });
-
- it('getLookupKey() should return correct object', function() {
- let key = cnvrHelper.getLookupKey(undefined, undefined, undefined);
- expect(key).to.equal('undefined-undefined-undefined');
-
- key = cnvrHelper.getLookupKey('foo', 'bar', 'baz');
- expect(key).to.equal('foo-bar-baz');
- });
-
- it('createPayload() should return correct object', function() {
- const REQUEST_TYPE = 'foo';
- const AUCTION_ID = '124 abc';
- const myDate = Date.now();
- conversantAnalytics.enableAnalytics(VALID_ALWAYS_SAMPLE_CONFIG);
-
- const payload = cnvrHelper.createPayload(REQUEST_TYPE, AUCTION_ID, myDate);
- expect(payload).to.deep.equal({
- bidderErrors: [],
- cnvrSampleRate: 1,
- globalSampleRate: 1,
- requestType: REQUEST_TYPE,
- auction: {
- auctionId: AUCTION_ID,
- auctionTimestamp: myDate,
- sid: VALID_ALWAYS_SAMPLE_CONFIG.options.site_id,
- preBidVersion: PREBID_VERSION
- },
- adUnits: {}
- });
- });
-
- it('keyExistsAndIsObject() should return correct data', function() {
- const data = {
- a: [],
- b: 1,
- c: 'foo',
- d: function () { return true; },
- e: {}
- };
- expect(cnvrHelper.keyExistsAndIsObject(data, 'foobar')).to.be.false;
- expect(cnvrHelper.keyExistsAndIsObject(data, 'a')).to.be.false;
- expect(cnvrHelper.keyExistsAndIsObject(data, 'b')).to.be.false;
- expect(cnvrHelper.keyExistsAndIsObject(data, 'c')).to.be.false;
- expect(cnvrHelper.keyExistsAndIsObject(data, 'd')).to.be.false;
- expect(cnvrHelper.keyExistsAndIsObject(data, 'e')).to.be.true;
- });
-
- it('deduplicateArray() should return correct data', function () {
- const arrayOfObjects = [{ w: 1, h: 2 }, { w: 2, h: 3 }, { w: 1, h: 2 }];
- const array = [3, 2, 1, 1, 2, 3];
- let empty;
- const notArray = 3;
- const emptyArray = [];
-
- expect(JSON.stringify(cnvrHelper.deduplicateArray(array))).to.equal(JSON.stringify([3, 2, 1]));
- expect(JSON.stringify(cnvrHelper.deduplicateArray(arrayOfObjects))).to.equal(JSON.stringify([{ w: 1, h: 2 }, { w: 2, h: 3 }]));
- expect(JSON.stringify(cnvrHelper.deduplicateArray(emptyArray))).to.equal(JSON.stringify([]));
- expect(cnvrHelper.deduplicateArray(empty)).to.be.undefined;
- expect(cnvrHelper.deduplicateArray(notArray)).to.equal(notArray);
- });
-
- it('getSampleRate() should return correct data', function () {
- const obj = {
- sampling: 1,
- cnvr_sampling: 0.5,
- too_big: 1.2,
- too_small: -1,
- string: 'foo',
- object: {},
- }
- const DEFAULT_VAL = 0.11;
- expect(cnvrHelper.getSampleRate(obj, 'sampling', DEFAULT_VAL)).to.equal(1);
- expect(cnvrHelper.getSampleRate(obj, 'cnvr_sampling', DEFAULT_VAL)).to.equal(0.5);
- expect(cnvrHelper.getSampleRate(obj, 'too_big', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
- expect(cnvrHelper.getSampleRate(obj, 'string', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
- expect(cnvrHelper.getSampleRate(obj, 'object', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
- expect(cnvrHelper.getSampleRate(obj, 'not_a_key', DEFAULT_VAL)).to.equal(DEFAULT_VAL);
- expect(cnvrHelper.getSampleRate(obj, 'too_small', DEFAULT_VAL)).to.equal(0);
- });
-
- it('getPageUrl() should return correct data', function() {
- const url = cnvrHelper.getPageUrl();
- expect(url.length).to.be.above(1);
- });
-
- it('sendErrorData() should send data via ajax', function() {
- const error = {
- stack: 'foobar',
- message: 'foobar message'
- };
- const eventType = 'fooType';
-
- expect(requests).to.have.lengthOf(0);
- cnvrHelper.sendErrorData(eventType, error);
- expect(requests).to.have.lengthOf(1);
-
- expect(requests[0].url).to.contain('cvx/event/prebidanalyticerrors');
- const data = JSON.parse(requests[0].requestBody);
- expect(data.event).to.be.equal(eventType);
- expect(data.siteId).to.be.equal(SITE_ID);
- expect(data.message).to.not.be.undefined;
- expect(data.prebidVersion).to.not.be.undefined;
- expect(data.userAgent).to.not.be.undefined;
- expect(data.url).to.not.be.undefined;
- });
-
- it('Should not send data when error logging disabled', function() {
- const error = {
- stack: 'foobar',
- message: 'foobar message'
- };
- const eventType = 'fooType';
-
- conversantAnalytics.disableAnalytics();
- conversantAnalytics.enableAnalytics({
- options: {
- site_id: SITE_ID,
- cnvr_sampling: 1,
- send_error_data: false
- }
- });
- expect(cnvrHelper.doSendErrorData).to.be.false;
-
- expect(requests).to.have.lengthOf(0);
- cnvrHelper.sendErrorData(eventType, error);
- expect(requests).to.have.lengthOf(0);
-
- conversantAnalytics.disableAnalytics();
- conversantAnalytics.enableAnalytics({
- options: {
- site_id: SITE_ID,
- cnvr_sampling: 1,
- send_error_data: 0
- }
- });
- expect(cnvrHelper.doSendErrorData).to.be.false;
-
- expect(requests).to.have.lengthOf(0);
- cnvrHelper.sendErrorData(eventType, error);
- expect(requests).to.have.lengthOf(0);
- });
- });
-
- describe('Bid Timeout Event Tests', function() {
- const BID_TIMEOUT_PAYLOAD = [{
- bidId: '80882409358b8a8',
- bidder: 'conversant',
- adUnitCode: 'MedRect',
- auctionId: 'afbd6e0b-e45b-46ab-87bf-c0bac0cb8881'
- }, {
- bidId: '9da4c107a6f24c8',
- bidder: 'conversant',
- adUnitCode: 'Leaderboard',
- auctionId: 'afbd6e0b-e45b-46ab-87bf-c0bac0cb8881'
- }];
-
- it('should put both items in timeout cache', function() {
- expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(0);
- events.emit(EVENTS.BID_TIMEOUT, BID_TIMEOUT_PAYLOAD);
- expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(2);
-
- BID_TIMEOUT_PAYLOAD.forEach(timeoutBid => {
- const key = cnvrHelper.getLookupKey(timeoutBid.auctionId, timeoutBid.adUnitCode, timeoutBid.bidder);
- expect(cnvrHelper.timeoutCache[key].timeReceived).to.not.be.undefined;
- });
- expect(requests).to.have.lengthOf(0);
- });
- });
-
- describe('Render Failed Tests', function() {
- const RENDER_FAILED_PAYLOAD = {
- reason: 'reason',
- message: 'value',
- adId: '57e03aeafd83a68'
- };
-
- const RENDER_FAILED_PAYLOAD_NO_ADID = {
- reason: 'reason',
- message: 'value'
- };
-
- it('should empty adIdLookup and send data', function() {
- cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId] = {
- bidderCode: 'bidderCode',
- adUnitCode: 'adUnitCode',
- auctionId: 'auctionId',
- timeReceived: Date.now()
- };
-
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
- events.emit(EVENTS.AD_RENDER_FAILED, RENDER_FAILED_PAYLOAD);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0); // object should be removed
- expect(requests).to.have.lengthOf(1);
- const data = JSON.parse(requests[0].requestBody);
-
- expect(data.auction.auctionId).to.equal('auctionId');
- expect(data.auction.preBidVersion).to.equal(PREBID_VERSION);
- expect(data.auction.sid).to.equal(SITE_ID);
- expect(data.adUnits.adUnitCode.bids.bidderCode[0].eventCodes.includes(CNVR_CONSTANTS.RENDER_FAILED)).to.be.true;
- expect(data.adUnits.adUnitCode.bids.bidderCode[0].message).to.have.lengthOf.above(0);
- });
-
- it('should not send data if no adId', function() {
- cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId] = {
- bidderCode: 'bidderCode',
- adUnitCode: 'adUnitCode',
- auctionId: 'auctionId',
- timeReceived: Date.now()
- };
-
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
- events.emit(EVENTS.AD_RENDER_FAILED, RENDER_FAILED_PAYLOAD_NO_ADID);
- expect(requests).to.have.lengthOf(1);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1); // same object in cache as before... no change
- expect(cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId]).to.not.be.undefined;
-
- expect(requests[0].url).to.contain('cvx/event/prebidanalyticerrors');
- const data = JSON.parse(requests[0].requestBody);
- expect(data.event).to.be.equal(EVENTS.AD_RENDER_FAILED);
- expect(data.siteId).to.be.equal(SITE_ID);
- expect(data.message).to.not.be.undefined;
- expect(data.prebidVersion).to.not.be.undefined;
- expect(data.userAgent).to.not.be.undefined;
- expect(data.url).to.not.be.undefined;
- });
-
- it('should not send data if bad data in lookup', function() {
- cnvrHelper.adIdLookup[RENDER_FAILED_PAYLOAD.adId] = {
- bidderCode: 'bidderCode',
- auctionId: 'auctionId',
- timeReceived: Date.now()
- };
- expect(requests).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
- events.emit(EVENTS.AD_RENDER_FAILED, RENDER_FAILED_PAYLOAD);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0); // object should be removed but no call made to send data
- expect(requests).to.have.lengthOf(1);
-
- expect(requests[0].url).to.contain('cvx/event/prebidanalyticerrors');
- const data = JSON.parse(requests[0].requestBody);
- expect(data.event).to.be.equal(EVENTS.AD_RENDER_FAILED);
- expect(data.siteId).to.be.equal(SITE_ID);
- expect(data.message).to.not.be.undefined;
- expect(data.prebidVersion).to.not.be.undefined;
- expect(data.userAgent).to.not.be.undefined;
- expect(data.url).to.not.be.undefined;
- });
- });
-
- describe('Bid Won Tests', function() {
- const GOOD_BID_WON_ARGS = {
- bidderCode: 'conversant',
- width: 300,
- height: 250,
- statusMessage: 'Bid available',
- adId: '57e03aeafd83a68',
- requestId: '2c2a5485a076898',
- mediaType: 'banner',
- source: 'client',
- currency: 'USD',
- cpm: 4,
- creativeId: '29123_55016759',
- ttl: 300,
- netRevenue: true,
- ad: '',
- originalCpm: 0.04,
- originalCurrency: 'USD',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- responseTimestamp: 1583851418626,
- requestTimestamp: 1583851418292,
- bidder: 'conversant',
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- timeToRespond: 334,
- pbLg: '4.00',
- pbMg: '4.00',
- pbHg: '4.00',
- pbAg: '4.00',
- pbDg: '4.00',
- pbCg: '',
- size: '300x250',
- adserverTargeting: {
- hb_bidder: 'conversant',
- hb_adid: '57e03aeafd83a68',
- hb_pb: '4.00',
- hb_size: '300x250',
- hb_source: 'client',
- hb_format: 'banner'
- },
- status: 'rendered',
- params: [
- {
- site_id: '108060'
- }
- ]
- };
-
- // no adUnitCode, auctionId or bidderCode will cause a failure
- const BAD_BID_WON_ARGS = {
- bidderCode: 'conversant',
- width: 300,
- height: 250,
- statusMessage: 'Bid available',
- adId: '57e03aeafd83a68',
- requestId: '2c2a5485a076898',
- mediaType: 'banner',
- source: 'client',
- currency: 'USD',
- cpm: 4,
- originalCpm: 0.04,
- originalCurrency: 'USD',
- bidder: 'conversant',
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- size: '300x250',
- status: 'rendered',
- params: [
- {
- site_id: '108060'
- }
- ]
- };
-
- it('should not send data or put a record in adIdLookup when bad data provided', function() {
- expect(requests).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
- events.emit(EVENTS.BID_WON, BAD_BID_WON_ARGS);
- expect(requests).to.have.lengthOf(1);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
-
- // check for error event
- expect(requests[0].url).to.contain('cvx/event/prebidanalyticerrors');
- const data = JSON.parse(requests[0].requestBody);
- expect(data.event).to.be.equal(EVENTS.BID_WON);
- expect(data.siteId).to.be.equal(SITE_ID);
- expect(data.message).to.not.be.undefined;
- expect(data.prebidVersion).to.not.be.undefined;
- expect(data.userAgent).to.not.be.undefined;
- expect(data.url).to.not.be.undefined;
- });
-
- it('should send data and put a record in adIdLookup', function() {
- const myAuctionStart = Date.now();
- cnvrHelper.auctionIdTimestampCache[GOOD_BID_WON_ARGS.auctionId] = { timeReceived: myAuctionStart };
-
- expect(requests).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(0);
- events.emit(EVENTS.BID_WON, GOOD_BID_WON_ARGS);
-
- // Check that adIdLookup was set correctly
- expect(Object.keys(cnvrHelper.adIdLookup)).to.have.lengthOf(1);
- expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].auctionId).to.equal(GOOD_BID_WON_ARGS.auctionId);
- expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].adUnitCode).to.equal(GOOD_BID_WON_ARGS.adUnitCode);
- expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].bidderCode).to.equal(GOOD_BID_WON_ARGS.bidderCode);
- expect(cnvrHelper.adIdLookup[GOOD_BID_WON_ARGS.adId].timeReceived).to.not.be.undefined;
-
- expect(requests).to.have.lengthOf(1);
- const data = JSON.parse(requests[0].requestBody);
- expect(data.requestType).to.equal('bid_won');
- expect(data.auction.auctionId).to.equal(GOOD_BID_WON_ARGS.auctionId);
- expect(data.auction.preBidVersion).to.equal(PREBID_VERSION);
- expect(data.auction.sid).to.equal(VALID_ALWAYS_SAMPLE_CONFIG.options.site_id);
- expect(data.auction.auctionTimestamp).to.equal(myAuctionStart);
-
- expect(typeof data.adUnits).to.equal('object');
- expect(Object.keys(data.adUnits)).to.have.lengthOf(1);
-
- expect(Object.keys(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids)).to.have.lengthOf(1);
- expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].eventCodes.includes(CNVR_CONSTANTS.WIN)).to.be.true;
- expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].cpm).to.equal(GOOD_BID_WON_ARGS.cpm);
- expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].originalCpm).to.equal(GOOD_BID_WON_ARGS.originalCpm);
- expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].currency).to.equal(GOOD_BID_WON_ARGS.currency);
- expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].timeToRespond).to.equal(GOOD_BID_WON_ARGS.timeToRespond);
- expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].adSize.w).to.equal(GOOD_BID_WON_ARGS.width);
- expect(data.adUnits[GOOD_BID_WON_ARGS.adUnitCode].bids[GOOD_BID_WON_ARGS.bidderCode][0].adSize.h).to.equal(GOOD_BID_WON_ARGS.height);
- });
- });
-
- describe('Auction End Tests', function() {
- const AUCTION_END_PAYLOAD = {
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- timestamp: 1583851418288,
- auctionEnd: 1583851418628,
- auctionStatus: 'completed',
- adUnits: [
- {
- code: 'div-gpt-ad-1460505748561-0',
- mediaTypes: {
- banner: {
- sizes: [
- [300, 250],
- [100, 200]
- ]
- }
- },
- bids: [
- {
- bidder: 'appnexus',
- params: {
- placementId: 13144370
- }
- },
- {
- bidder: 'conversant',
- params: {
- site_id: '108060'
- }
- }
- ],
- sizes: [
- [300, 250],
- [100, 200]
- ],
- transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17'
- },
- {
- code: 'div-gpt-ad-1460505748561-0',
- mediaTypes: {
- banner: {
- sizes: [
- [300, 250],
- [100, 200]
- ]
- },
- video: {
- playerSize: [
- [300, 250],
- [600, 400]
- ]
- }
- },
- sizes: [
- [300, 250],
- [100, 200],
- [600, 400]
- ],
- bids: [
- {
- bidder: 'appnexus',
- params: {
- placementId: 13144370
- }
- },
- {
- bidder: 'conversant',
- params: {
- site_id: '108060'
- }
- }
- ],
- transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba18'
- },
- {
- code: 'div-gpt-ad-1460505748561-1',
- mediaTypes: {
- native: {
- type: 'image'
- }
- },
- bids: [
- {
- bidder: 'appnexus',
- params: {
- placementId: 13144371
- }
- }
- ],
- transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba10'
- }
- ],
- adUnitCodes: [
- 'div-gpt-ad-1460505748561-0'
- ],
- bidderRequests: [
- {
- bidderCode: 'conversant',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- bidderRequestId: '13f16db358d4c58',
- bids: [
- {
- bidder: 'conversant',
- params: {
- site_id: '108060'
- },
- mediaTypes: {
- banner: {
- sizes: [
- [
- 300,
- 250
- ]
- ]
- }
- },
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
- sizes: [
- [
- 300,
- 250
- ]
- ],
- bidId: '2c2a5485a076898',
- bidderRequestId: '13f16db358d4c58',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- src: 'client',
- bidRequestsCount: 1,
- bidderRequestsCount: 1,
- bidderWinsCount: 0
- }
- ],
- auctionStart: 1583851418288,
- timeout: 3000,
- refererInfo: {
- referer: 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html',
- reachedTop: true,
- numIframes: 0,
- stack: [
- 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html'
- ]
- },
- start: 1583851418292
- },
- {
- bidderCode: 'appnexus',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- bidderRequestId: '3e8179f67f31b98',
- bids: [
- {
- bidder: 'appnexus',
- params: {
- placementId: 13144370
- },
- mediaTypes: {
- banner: {
- sizes: [
- [
- 300,
- 250
- ]
- ]
- }
- },
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
- sizes: [
- [
- 300,
- 250
- ]
- ],
- bidId: '40a1d3ac6b79668',
- bidderRequestId: '3e8179f67f31b98',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- src: 'client',
- bidRequestsCount: 1,
- bidderRequestsCount: 1,
- bidderWinsCount: 0
- },
- {
- bidder: 'appnexus',
- params: {
- placementId: 13144370
- },
- mediaTypes: {
- native: {
- type: 'image'
- }
- },
- adUnitCode: 'div-gpt-ad-1460505748561-1',
- transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
- sizes: [],
- bidId: '40a1d3ac6b79668',
- bidderRequestId: '3e8179f67f31b98',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- src: 'client',
- bidRequestsCount: 1,
- bidderRequestsCount: 1,
- bidderWinsCount: 0
- }
- ],
- auctionStart: 1583851418288,
- timeout: 3000,
- refererInfo: {
- referer: 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html',
- reachedTop: true,
- numIframes: 0,
- stack: [
- 'http://localhost:9999/integrationExamples/gpt/hello_analytics1.html'
- ]
- },
- start: 1583851418295
- }
- ],
- noBids: [
- {
- bidder: 'appnexus',
- params: {
- placementId: 13144370
- },
- mediaTypes: {
- banner: {
- sizes: [
- [
- 300,
- 250
- ]
- ]
- }
- },
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- transactionId: '5fa8a7d7-2a73-4d1c-b73a-ff9f5b53ba17',
- sizes: [
- [
- 300,
- 250
- ]
- ],
- bidId: '40a1d3ac6b79668',
- bidderRequestId: '3e8179f67f31b98',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- src: 'client',
- bidRequestsCount: 1,
- bidderRequestsCount: 1,
- bidderWinsCount: 0
- }
- ],
- bidsReceived: [
- {
- bidderCode: 'conversant',
- width: 300,
- height: 250,
- statusMessage: 'Bid available',
- adId: '57e03aeafd83a68',
- requestId: '2c2a5485a076898',
- mediaType: 'banner',
- source: 'client',
- currency: 'USD',
- cpm: 4,
- creativeId: '29123_55016759',
- ttl: 300,
- netRevenue: true,
- ad: '',
- originalCpm: 0.04,
- originalCurrency: 'USD',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- responseTimestamp: 1583851418626,
- requestTimestamp: 1583851418292,
- bidder: 'conversant',
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- timeToRespond: 334,
- pbLg: '4.00',
- pbMg: '4.00',
- pbHg: '4.00',
- pbAg: '4.00',
- pbDg: '4.00',
- pbCg: '',
- size: '300x250',
- adserverTargeting: {
- hb_bidder: 'conversant',
- hb_adid: '57e03aeafd83a68',
- hb_pb: '4.00',
- hb_size: '300x250',
- hb_source: 'client',
- hb_format: 'banner'
- }
- }, {
- bidderCode: 'conversant',
- height: 100,
- statusMessage: 'Bid available',
- width: 200,
- adId: '57e03aeafd83a68',
- requestId: '2c2a5485a076898',
- mediaType: 'banner',
- source: 'client',
- currency: 'USD',
- cpm: 4,
- creativeId: '29123_55016759',
- ttl: 300,
- netRevenue: true,
- ad: '',
- originalCpm: 0.04,
- originalCurrency: 'USD',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- responseTimestamp: 1583851418626,
- requestTimestamp: 1583851418292,
- bidder: 'conversant',
- adUnitCode: 'div-gpt-ad-1460505748561-0',
- timeToRespond: 334,
- pbLg: '4.00',
- pbMg: '4.00',
- pbHg: '4.00',
- pbAg: '4.00',
- pbDg: '4.00',
- pbCg: '',
- size: '100x200',
- adserverTargeting: {
- hb_bidder: 'conversant',
- hb_adid: '57e03aeafd83a68',
- hb_pb: '4.00',
- hb_size: '300x250',
- hb_source: 'client',
- hb_format: 'banner'
- }
- }, {
- bidderCode: 'appnexus',
- statusMessage: 'Bid available',
- adId: '57e03aeafd83a68',
- requestId: '2c2a5485a076898',
- mediaType: 'native',
- source: 'client',
- currency: 'USD',
- cpm: 4,
- creativeId: '29123_55016759',
- ttl: 300,
- netRevenue: true,
- ad: '',
- originalCpm: 0.04,
- originalCurrency: 'USD',
- auctionId: '85e1bf44-4035-4e24-bd3c-b1ba367fe294',
- responseTimestamp: 1583851418626,
- requestTimestamp: 1583851418292,
- bidder: 'appnexus',
- adUnitCode: 'div-gpt-ad-1460505748561-1',
- timeToRespond: 334,
- pbLg: '4.00',
- pbMg: '4.00',
- pbHg: '4.00',
- pbAg: '4.00',
- pbDg: '4.00',
- pbCg: '',
- adserverTargeting: {
- hb_bidder: 'appnexus',
- hb_adid: '57e03aeafd83a68',
- hb_pb: '4.00',
- hb_size: '300x250',
- hb_source: 'client',
- hb_format: 'banner'
- }
- }
- ],
- winningBids: [],
- timeout: 3000
- };
-
- it('should not do anything when auction id doesnt exist', function() {
- sandbox.stub(utils, 'logError');
-
- const BAD_ARGS = JSON.parse(JSON.stringify(AUCTION_END_PAYLOAD));
- delete BAD_ARGS.auctionId;
- expect(requests).to.have.lengthOf(0);
- events.emit(EVENTS.AUCTION_END, BAD_ARGS);
- expect(requests).to.have.lengthOf(1);
-
- // check for error event
- expect(requests[0].url).to.contain('cvx/event/prebidanalyticerrors');
- const data = JSON.parse(requests[0].requestBody);
- expect(data.event).to.be.equal(EVENTS.AUCTION_END);
- expect(data.siteId).to.be.equal(SITE_ID);
- expect(data.message).to.not.be.undefined;
- expect(data.prebidVersion).to.not.be.undefined;
- expect(data.userAgent).to.not.be.undefined;
- expect(data.url).to.not.be.undefined;
- });
-
- it('should send the expected data', function() {
- sandbox.stub(utils, 'logError');
- sandbox.stub(utils, 'logWarn');
-
- expect(requests).to.have.lengthOf(0);
- const AUCTION_ID = AUCTION_END_PAYLOAD.auctionId;
- const AD_UNIT_CODE = AUCTION_END_PAYLOAD.adUnits[0].code;
- const AD_UNIT_CODE_NATIVE = AUCTION_END_PAYLOAD.adUnits[2].code;
- const timeoutKey = cnvrHelper.getLookupKey(AUCTION_ID, AD_UNIT_CODE, 'appnexus');
- const URL = 'some url';
- cnvrHelper.bidderErrorCache[AUCTION_ID] = {
- errors: [{
- status: 500,
- message: 'error msg',
- bidderCode: 'bidderCode',
- url: URL,
- }, {
- status: 501,
- message: 'error msg1',
- bidderCode: 'bidderCode1',
- url: URL,
- }],
- timeReceived: Date.now()
- };
- cnvrHelper.timeoutCache[timeoutKey] = { timeReceived: Date.now() };
- expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(1);
- expect(utils.logError.called).to.equal(false);
- expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.bidderErrorCache)).to.have.lengthOf(1);
-
- events.emit(EVENTS.AUCTION_END, AUCTION_END_PAYLOAD);
- expect(utils.logError.called).to.equal(false);
- expect(requests).to.have.lengthOf(1);
- expect(Object.keys(cnvrHelper.timeoutCache)).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.auctionIdTimestampCache)).to.have.lengthOf(1);
- expect(cnvrHelper.auctionIdTimestampCache[AUCTION_END_PAYLOAD.auctionId].timeReceived).to.equal(AUCTION_END_PAYLOAD.timestamp);
-
- const data = JSON.parse(requests[0].requestBody);
- expect(data.requestType).to.equal('auction_end');
- expect(data.auction.auctionId).to.equal(AUCTION_ID);
- expect(data.auction.preBidVersion).to.equal(PREBID_VERSION);
- expect(data.auction.sid).to.equal(VALID_ALWAYS_SAMPLE_CONFIG.options.site_id);
-
- expect(Object.keys(data.adUnits)).to.have.lengthOf(2);
-
- expect(data.adUnits[AD_UNIT_CODE].sizes).to.have.lengthOf(3);
- expect(data.adUnits[AD_UNIT_CODE].sizes[0].w).to.equal(300);
- expect(data.adUnits[AD_UNIT_CODE].sizes[0].h).to.equal(250);
- expect(data.adUnits[AD_UNIT_CODE].sizes[1].w).to.equal(100);
- expect(data.adUnits[AD_UNIT_CODE].sizes[1].h).to.equal(200);
- expect(data.adUnits[AD_UNIT_CODE].sizes[2].w).to.equal(600);
- expect(data.adUnits[AD_UNIT_CODE].sizes[2].h).to.equal(400);
-
- expect(data.adUnits[AD_UNIT_CODE].mediaTypes).to.have.lengthOf(2);
- expect(data.adUnits[AD_UNIT_CODE].mediaTypes[0]).to.equal('banner');
- expect(data.adUnits[AD_UNIT_CODE].mediaTypes[1]).to.equal('video');
-
- expect(data.adUnits[AD_UNIT_CODE_NATIVE].mediaTypes).to.have.lengthOf(1);
- expect(data.adUnits[AD_UNIT_CODE_NATIVE].mediaTypes[0]).to.equal('native');
- expect(data.adUnits[AD_UNIT_CODE_NATIVE].sizes).to.have.lengthOf(0);
-
- expect(Object.keys(data.adUnits[AD_UNIT_CODE].bids)).to.have.lengthOf(2);
- const cnvrBidsArray = data.adUnits[AD_UNIT_CODE].bids.conversant;
- // testing multiple bids from same bidder
- expect(cnvrBidsArray).to.have.lengthOf(2);
- expect(cnvrBidsArray[0].eventCodes.includes(CNVR_CONSTANTS.BID)).to.be.true;
- expect(cnvrBidsArray[0].cpm).to.equal(4);
- expect(cnvrBidsArray[0].originalCpm).to.equal(0.04);
- expect(cnvrBidsArray[0].currency).to.equal('USD');
- expect(cnvrBidsArray[0].timeToRespond).to.equal(334);
- expect(cnvrBidsArray[0].adSize.w).to.equal(300);
- expect(cnvrBidsArray[0].adSize.h).to.equal(250);
- expect(cnvrBidsArray[0].mediaType).to.equal('banner');
- // 2nd bid different size
- expect(cnvrBidsArray[1].eventCodes.includes(CNVR_CONSTANTS.BID)).to.be.true;
- expect(cnvrBidsArray[1].cpm).to.equal(4);
- expect(cnvrBidsArray[1].originalCpm).to.equal(0.04);
- expect(cnvrBidsArray[1].currency).to.equal('USD');
- expect(cnvrBidsArray[1].timeToRespond).to.equal(334);
- expect(cnvrBidsArray[1].adSize.w).to.equal(200);
- expect(cnvrBidsArray[1].adSize.h).to.equal(100);
- expect(cnvrBidsArray[1].mediaType).to.equal('banner');
-
- const apnBidsArray = data.adUnits[AD_UNIT_CODE].bids.appnexus;
- expect(apnBidsArray).to.have.lengthOf(2);
- let apnBid = apnBidsArray[0];
- expect(apnBid.originalCpm).to.be.undefined;
- expect(apnBid.eventCodes.includes(CNVR_CONSTANTS.TIMEOUT)).to.be.true;
- expect(apnBid.cpm).to.be.undefined;
- expect(apnBid.currency).to.be.undefined;
- expect(apnBid.timeToRespond).to.equal(3000);
- expect(apnBid.adSize).to.be.undefined;
- expect(apnBid.mediaType).to.be.undefined;
- apnBid = apnBidsArray[1];
- expect(apnBid.originalCpm).to.be.undefined;
- expect(apnBid.eventCodes.includes(CNVR_CONSTANTS.NO_BID)).to.be.true;
- expect(apnBid.cpm).to.be.undefined;
- expect(apnBid.currency).to.be.undefined;
- expect(apnBid.timeToRespond).to.equal(0);
- expect(apnBid.adSize).to.be.undefined;
- expect(apnBid.mediaType).to.be.undefined;
-
- expect(Object.keys(data.adUnits[AD_UNIT_CODE_NATIVE].bids)).to.have.lengthOf(1);
- const apnNativeBidsArray = data.adUnits[AD_UNIT_CODE_NATIVE].bids.appnexus;
- expect(apnNativeBidsArray).to.have.lengthOf(1);
- const apnNativeBid = apnNativeBidsArray[0];
- expect(apnNativeBid.eventCodes.includes(CNVR_CONSTANTS.BID)).to.be.true;
- expect(apnNativeBid.cpm).to.equal(4);
- expect(apnNativeBid.originalCpm).to.equal(0.04);
- expect(apnNativeBid.currency).to.equal('USD');
- expect(apnNativeBid.timeToRespond).to.equal(334);
- expect(apnNativeBid.adSize.w).to.be.undefined;
- expect(apnNativeBid.adSize.h).to.be.undefined;
- expect(apnNativeBid.mediaType).to.equal('native');
-
- expect(Object.keys(data.bidderErrors)).to.have.lengthOf(2);
- expect(data.bidderErrors[0].status).to.equal(500);
- expect(data.bidderErrors[0].url).to.equal(URL);
- expect(data.bidderErrors[0].message).to.not.be.undefined;
- expect(data.bidderErrors[0].bidderCode).to.not.be.undefined;
-
- expect(data.bidderErrors[1].status).to.equal(501);
- expect(data.bidderErrors[1].url).to.equal(URL);
- expect(data.bidderErrors[1].message).to.not.be.undefined;
- expect(data.bidderErrors[1].bidderCode).to.not.be.undefined;
-
- expect(Object.keys(cnvrHelper.bidderErrorCache)).to.have.lengthOf(0);
- });
- });
-
- describe('Bidder Error Tests', function() {
- // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
- const XHR_ERROR_MOCK = {
- status: 500,
- statusText: 'Internal Server Error'
- };
-
- // https://docs.prebid.org/dev-docs/bidder-adaptor.html#registering-on-bidder-error
- const MOCK_BID_REQUEST = {
- auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917',
- auctionStart: 1579746300522,
- bidderCode: 'myBidderCode',
- bidderRequestId: '15246a574e859f',
- bids: [{}],
- gdprConsent: { consentString: 'BOtmiBKOtmiBKABABAENAFAAAAACeAAA', vendorData: {}, gdprApplies: true },
- refererInfo: {
- canonicalUrl: null,
- page: 'http://mypage.org?pbjs_debug=true',
- domain: 'mypage.org',
- ref: null,
- numIframes: 0,
- reachedTop: true,
- isAmp: false,
- stack: ['http://mypage.org?pbjs_debug=true']
- }
- };
-
- it('should record error when bidder_error called', function() {
- const warnStub = sandbox.stub(utils, 'logWarn');
- expect(requests).to.have.lengthOf(0);
- expect(Object.keys(cnvrHelper.bidderErrorCache)).to.have.lengthOf(0);
- expect(warnStub.calledOnce).to.be.false;
-
- events.emit(EVENTS.BIDDER_ERROR, { error: XHR_ERROR_MOCK, bidderRequest: MOCK_BID_REQUEST });
- expect(Object.keys(cnvrHelper.bidderErrorCache)).to.have.lengthOf(1);
- expect(warnStub.calledOnce).to.be.true;
-
- let errorObj = cnvrHelper.bidderErrorCache[MOCK_BID_REQUEST.auctionId];
- expect(errorObj.errors).to.have.lengthOf(1);
- expect(errorObj.errors[0].status).to.equal(XHR_ERROR_MOCK.status);
- expect(errorObj.errors[0].message).to.equal(XHR_ERROR_MOCK.statusText);
- expect(errorObj.errors[0].bidderCode).to.equal(MOCK_BID_REQUEST.bidderCode);
- expect(errorObj.errors[0].url).to.not.be.undefined;
-
- events.emit(EVENTS.BIDDER_ERROR, { error: XHR_ERROR_MOCK, bidderRequest: MOCK_BID_REQUEST });
- errorObj = cnvrHelper.bidderErrorCache[MOCK_BID_REQUEST.auctionId];
- expect(errorObj.errors).to.have.lengthOf(2);
- });
- });
-});
diff --git a/test/spec/modules/limelightDigitalBidAdapter_spec.js b/test/spec/modules/limelightDigitalBidAdapter_spec.js
index b13beb26d28..c84586e9064 100644
--- a/test/spec/modules/limelightDigitalBidAdapter_spec.js
+++ b/test/spec/modules/limelightDigitalBidAdapter_spec.js
@@ -516,10 +516,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-lm.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
@@ -543,10 +543,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-1.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-1.ortb.net/sync.html';
}
}
@@ -578,10 +578,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-lm.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
@@ -605,10 +605,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-1.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-1.ortb.net/sync.html';
}
}
@@ -618,10 +618,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-2.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-2.ortb.net/sync.html';
}
}
@@ -649,10 +649,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-lm.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
@@ -662,10 +662,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-lm.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
@@ -689,10 +689,10 @@ describe('limelightDigitalAdapter', function () {
{
headers: {
get: function (header) {
- if (header === 'X-PLL-UserSync-Image') {
+ if (header === 'x-pll-usersync-image') {
return 'https://tracker-lm.ortb.net/sync';
}
- if (header === 'X-PLL-UserSync-Iframe') {
+ if (header === 'x-pll-usersync-iframe') {
return 'https://tracker-lm.ortb.net/sync.html';
}
}
diff --git a/test/spec/modules/mediaforceBidAdapter_spec.js b/test/spec/modules/mediaforceBidAdapter_spec.js
index 61e5678b03b..ee88f0a21b8 100644
--- a/test/spec/modules/mediaforceBidAdapter_spec.js
+++ b/test/spec/modules/mediaforceBidAdapter_spec.js
@@ -1,7 +1,7 @@
import {assert} from 'chai';
import {spec} from 'modules/mediaforceBidAdapter.js';
import * as utils from '../../../src/utils.js';
-import {BANNER, NATIVE} from '../../../src/mediaTypes.js';
+import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js';
describe('mediaforce bid adapter', function () {
let sandbox;
@@ -76,7 +76,7 @@ describe('mediaforce bid adapter', function () {
sizes: [300, 250],
},
sponsoredBy: {
- required: true
+ required: false
}
},
mediaTypes: {
@@ -93,8 +93,20 @@ describe('mediaforce bid adapter', function () {
sizes: [300, 250],
},
sponsoredBy: {
- required: true
+ required: false
}
+ },
+ video: {
+ playerSize: [[640, 480]],
+ mimes: ['video/mp4'],
+ minduration: 5,
+ maxduration: 30,
+ protocols: [2, 3],
+ linearity: 1,
+ skip: 1,
+ skipmin: 5,
+ skipafter: 10,
+ api: [1, 2]
}
},
ortb2Imp: {
@@ -104,6 +116,82 @@ describe('mediaforce bid adapter', function () {
}
};
+ const refererInfo = {
+ ref: 'https://www.prebid.org',
+ reachedTop: true,
+ stack: [
+ 'https://www.prebid.org/page.html',
+ 'https://www.prebid.org/iframe1.html',
+ ]
+ };
+
+ const dnt = utils.getDNT() ? 1 : 0;
+ const secure = window.location.protocol === 'https:' ? 1 : 0;
+ const pageUrl = window.location.href;
+ const timeout = 1500;
+ const auctionId = '210a474e-88f0-4646-837f-4253b7cf14fb';
+
+ const expectedData = {
+ // id property removed as it is specific for each request generated
+ tmax: timeout,
+ ext: {
+ mediaforce: {
+ hb_key: auctionId
+ }
+ },
+ site: {
+ id: defaultBid.params.publisher_id,
+ publisher: {id: defaultBid.params.publisher_id},
+ ref: encodeURIComponent(refererInfo.ref),
+ page: pageUrl,
+ },
+ device: {
+ ua: navigator.userAgent,
+ dnt: dnt,
+ js: 1,
+ language: language,
+ },
+ imp: [{
+ tagid: defaultBid.params.placement_id,
+ secure: secure,
+ bidfloor: 0,
+ ext: {
+ mediaforce: {
+ transactionId: defaultBid.ortb2Imp.ext.tid,
+ }
+ },
+ banner: {w: 300, h: 250},
+ native: {
+ ver: '1.2',
+ request: {
+ assets: [
+ {id: 1, title: {len: 800}, required: 1},
+ {id: 3, img: {w: 300, h: 250, type: 3}, required: 1},
+ {id: 5, data: {type: 1}, required: 0}
+ ],
+ context: 1,
+ plcmttype: 1,
+ ver: '1.2'
+ }
+ },
+ video: {
+ mimes: ['video/mp4'],
+ minduration: 5,
+ maxduration: 30,
+ protocols: [2, 3],
+ w: 640,
+ h: 480,
+ startdelay: 0,
+ linearity: 1,
+ skip: 1,
+ skipmin: 5,
+ skipafter: 10,
+ playbackmethod: [1],
+ api: [1, 2]
+ }
+ }],
+ };
+
const multiBid = [
{
publisher_id: 'pub123',
@@ -139,30 +227,72 @@ describe('mediaforce bid adapter', function () {
}
});
- const refererInfo = {
- ref: 'https://www.prebid.org',
- reachedTop: true,
- stack: [
- 'https://www.prebid.org/page.html',
- 'https://www.prebid.org/iframe1.html',
- ]
- };
-
const requestUrl = `${baseUrl}/header_bid`;
- const dnt = utils.getDNT() ? 1 : 0;
- const secure = window.location.protocol === 'https:' ? 1 : 0;
- const pageUrl = window.location.href;
- const timeout = 1500;
it('should return undefined if no validBidRequests passed', function () {
assert.equal(spec.buildRequests([]), undefined);
});
+ it('should not stop on unsupported mediaType', function () {
+ const bid = utils.deepClone(defaultBid);
+ bid.mediaTypes.audio = { size: [300, 250] };
+
+ let bidRequests = [bid];
+ let bidderRequest = {
+ bids: bidRequests,
+ refererInfo: refererInfo,
+ timeout: timeout,
+ auctionId: auctionId,
+ };
+
+ let [request] = spec.buildRequests(bidRequests, bidderRequest);
+ let data = JSON.parse(request.data);
+
+ let expectedDataCopy = utils.deepClone(expectedData);
+ assert.exists(data.id);
+
+ expectedDataCopy.id = data.id
+ assert.deepEqual(data, expectedDataCopy);
+ });
+
it('should return proper request url: no refererInfo', function () {
let [request] = spec.buildRequests([defaultBid]);
assert.equal(request.url, requestUrl);
});
+ it('should use test endpoint when is_test is true', function () {
+ const bid = utils.deepClone(defaultBid);
+ bid.params.is_test = true;
+
+ const [request] = spec.buildRequests([bid]);
+ assert.equal(request.url, `${baseUrl}/header_bid?debug_key=abcdefghijklmnop`);
+ });
+
+ it('should include aspect_ratios in native asset', function () {
+ const bid = utils.deepClone(defaultBid);
+ const aspect_ratios = [{
+ min_width: 100,
+ ratio_width: 4,
+ ratio_height: 3
+ }]
+ bid.mediaTypes.native.image.aspect_ratios = aspect_ratios;
+ bid.nativeParams.image.aspect_ratios = aspect_ratios;
+
+ const [request] = spec.buildRequests([bid]);
+ const nativeAsset = JSON.parse(request.data).imp[0].native.request.assets.find(a => a.id === 3);
+ assert.equal(nativeAsset.img.wmin, 100);
+ assert.equal(nativeAsset.img.hmin, 75);
+ });
+
+ it('should include placement in video object if provided', function () {
+ const bid = utils.deepClone(defaultBid);
+ bid.mediaTypes.video.placement = 2;
+
+ const [request] = spec.buildRequests([bid]);
+ const video = JSON.parse(request.data).imp[0].video;
+ assert.equal(video.placement, 2, 'placement should be passed into video object');
+ });
+
it('should return proper banner imp', function () {
let bid = utils.deepClone(defaultBid);
bid.params.bidfloor = 0;
@@ -172,63 +302,19 @@ describe('mediaforce bid adapter', function () {
bids: bidRequests,
refererInfo: refererInfo,
timeout: timeout,
- auctionId: '210a474e-88f0-4646-837f-4253b7cf14fb'
+ auctionId: auctionId,
};
let [request] = spec.buildRequests(bidRequests, bidderRequest);
let data = JSON.parse(request.data);
- assert.deepEqual(data, {
- id: data.id,
- tmax: timeout,
- ext: {
- mediaforce: {
- hb_key: bidderRequest.auctionId
- }
- },
- site: {
- id: bid.params.publisher_id,
- publisher: {id: bid.params.publisher_id},
- ref: encodeURIComponent(refererInfo.ref),
- page: pageUrl,
- },
- device: {
- ua: navigator.userAgent,
- dnt: dnt,
- js: 1,
- language: language,
- },
- imp: [{
- tagid: bid.params.placement_id,
- secure: secure,
- bidfloor: bid.params.bidfloor,
- ext: {
- mediaforce: {
- transactionId: bid.ortb2Imp.ext.tid,
- }
- },
- banner: {w: 300, h: 250},
- native: {
- ver: '1.2',
- request: {
- assets: [
- {id: 1, title: {len: 800}, required: 1},
- {id: 3, img: {w: 300, h: 250, type: 3}, required: 1},
- {id: 5, data: {type: 1}, required: 1}
- ],
- context: 1,
- plcmttype: 1,
- ver: '1.2'
- }
- },
- }],
- });
- assert.deepEqual(request, {
- method: 'POST',
- url: requestUrl,
- data: '{"id":"' + data.id + '","site":{"page":"' + pageUrl + '","ref":"https%3A%2F%2Fwww.prebid.org","id":"pub123","publisher":{"id":"pub123"}},"device":{"ua":"' + navigator.userAgent + '","js":1,"dnt":' + dnt + ',"language":"' + language + '"},"ext":{"mediaforce":{"hb_key":"210a474e-88f0-4646-837f-4253b7cf14fb"}},"tmax":1500,"imp":[{"tagid":"202","secure":' + secure + ',"bidfloor":0,"ext":{"mediaforce":{"transactionId":"d45dd707-a418-42ec-b8a7-b70a6c6fab0b"}},"banner":{"w":300,"h":250},"native":{"ver":"1.2","request":{"assets":[{"required":1,"id":1,"title":{"len":800}},{"required":1,"id":3,"img":{"type":3,"w":300,"h":250}},{"required":1,"id":5,"data":{"type":1}}],"context":1,"plcmttype":1,"ver":"1.2"}}}]}',
- });
+ let expectedDataCopy = utils.deepClone(expectedData);
+ assert.exists(data.id);
+
+ expectedDataCopy.id = data.id
+ expectedDataCopy.imp[0].bidfloor = bid.params.bidfloor
+ assert.deepEqual(data, expectedDataCopy);
});
it('multiple sizes', function () {
@@ -244,12 +330,22 @@ describe('mediaforce bid adapter', function () {
assert.deepEqual(data.imp[0].banner, {w: 300, h: 600, format: [{w: 300, h: 250}]});
});
+ it('should skip banner with empty sizes', function () {
+ const bid = utils.deepClone(defaultBid);
+ bid.mediaTypes.banner = { sizes: [] };
+
+ const [request] = spec.buildRequests([bid]);
+ const data = JSON.parse(request.data);
+ assert.notExists(data.imp[0].banner, 'Banner object should be omitted');
+ });
+
+
it('should return proper requests for multiple imps', function () {
let bidderRequest = {
bids: multiBid,
refererInfo: refererInfo,
timeout: timeout,
- auctionId: '210a474e-88f0-4646-837f-4253b7cf14fb'
+ auctionId: auctionId,
};
let requests = spec.buildRequests(multiBid, bidderRequest);
@@ -267,7 +363,7 @@ describe('mediaforce bid adapter', function () {
tmax: timeout,
ext: {
mediaforce: {
- hb_key: bidderRequest.auctionId
+ hb_key: auctionId
}
},
site: {
@@ -323,7 +419,7 @@ describe('mediaforce bid adapter', function () {
tmax: timeout,
ext: {
mediaforce: {
- hb_key: bidderRequest.auctionId
+ hb_key: auctionId
}
},
site: {
@@ -575,6 +671,50 @@ describe('mediaforce bid adapter', function () {
});
});
+ describe('interpretResponse() video', function () {
+ it('should interpret video response correctly', function () {
+ const vast = '...';
+
+ const bid = {
+ adid: '2_ssl',
+ adm: vast,
+ adomain: ["www3.thehealthyfat.com"],
+ burl: `${baseUrl}/burl/\${AUCTION_PRICE}`,
+ cat: ['IAB1-1'],
+ cid: '2_ssl',
+ crid: '2_ssl',
+ dealid: '3901521',
+ id: '65599d0a-42d2-446a-9d39-6086c1433ffe',
+ impid: '2b3c9d103723a7',
+ price: 5.5,
+ };
+
+ const response = {
+ body: {
+ seatbid: [{ bid: [bid] }],
+ cur: 'USD',
+ id: '620190c2-7eef-42fa-91e2-f5c7fbc2bdd3',
+ }
+ };
+
+ const [result] = spec.interpretResponse(response);
+
+ assert.deepEqual(result, {
+ burl: bid.burl,
+ cpm: bid.price,
+ creativeId: bid.adid,
+ currency: response.body.cur,
+ dealId: bid.dealid,
+ mediaType: VIDEO,
+ meta: { advertiserDomains: bid.adomain },
+ netRevenue: true,
+ requestId: bid.impid,
+ ttl: 300,
+ vastXml: vast,
+ });
+ });
+ });
+
describe('onBidWon()', function () {
beforeEach(function() {
sinon.stub(utils, 'triggerPixel');
diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js
index a274b141fd6..ac78b2b9ed1 100644
--- a/test/spec/modules/onetagBidAdapter_spec.js
+++ b/test/spec/modules/onetagBidAdapter_spec.js
@@ -3,6 +3,8 @@ import { expect } from 'chai';
import { find } from 'src/polyfill.js';
import { BANNER, VIDEO, NATIVE } from 'src/mediaTypes.js';
import { INSTREAM, OUTSTREAM } from 'src/video.js';
+import { toOrtbNativeRequest } from 'src/native.js';
+import { hasTypeNative } from '../../../modules/onetagBidAdapter';
const NATIVE_SUFFIX = 'Ad';
@@ -44,6 +46,57 @@ describe('onetag', function () {
};
}
+ function createNativeLegacyBid(bidRequest) {
+ let bid = bidRequest || createBid();
+ bid.mediaTypes = bid.mediaTypes || {};
+ bid.mediaTypes.native = {
+ adTemplate: "

##hb_native_brand####hb_native_title##
##hb_native_cta####hb_native_brand##
",
+ title: {
+ required: 1,
+ sendId: 1
+ },
+ body: {
+ required: 1,
+ sendId: 1
+ },
+ cta: {
+ required: 0,
+ sendId: 1
+ },
+ displayUrl: {
+ required: 0,
+ sendId: 1
+ },
+ icon: {
+ required: 0,
+ sendId: 1
+ },
+ image: {
+ required: 1,
+ sendId: 1
+ },
+ sponsoredBy: {
+ required: 1,
+ sendId: 1
+ }
+ }
+ bid = addNativeParams(bid);
+ const ortbConversion = toOrtbNativeRequest(bid.nativeParams);
+ bid.mediaTypes.native = {};
+ bid.mediaTypes.native.adTemplate = bid.nativeParams.adTemplate;
+ bid.mediaTypes.native.ortb = ortbConversion;
+ return bid;
+ }
+
+ function addNativeParams(bidRequest) {
+ let bidParams = bidRequest.nativeParams || {};
+ for (const property in bidRequest.mediaTypes.native) {
+ bidParams[property] = bidRequest.mediaTypes.native[property];
+ }
+ bidRequest.nativeParams = bidParams;
+ return bidRequest;
+ }
+
function createNativeBid(bidRequest) {
const bid = bidRequest || createBid();
bid.mediaTypes = bid.mediaTypes || {};
@@ -54,7 +107,7 @@ describe('onetag', function () {
assets: [{
id: 1,
required: 1,
- title: {
+ title: {
len: 140
}
},
@@ -81,7 +134,7 @@ describe('onetag', function () {
minduration: 5,
maxduration: 30,
protocols: [2, 3]
- }
+ }
}],
eventtrackers: [{
event: 1,
@@ -128,12 +181,13 @@ describe('onetag', function () {
return createInstreamVideoBid(createBannerBid());
}
- let bannerBid, instreamVideoBid, outstreamVideoBid, nativeBid;
+ let bannerBid, instreamVideoBid, outstreamVideoBid, nativeBid, nativeLegacyBid;
beforeEach(() => {
bannerBid = createBannerBid();
instreamVideoBid = createInstreamVideoBid();
outstreamVideoBid = createOutstreamVideoBid();
nativeBid = createNativeBid();
+ nativeLegacyBid = createNativeLegacyBid();
})
describe('isBidRequestValid', function () {
@@ -150,86 +204,94 @@ describe('onetag', function () {
});
describe('banner bidRequest', function () {
it('Should return false when the sizes array is empty', function () {
- // TODO (dgirardi): this test used to pass because `bannerBid` was global state
- // and other test code made it invalid for reasons other than sizes.
- // cleaning up the setup code, it now (correctly) fails.
- bannerBid.sizes = [];
- // expect(spec.isBidRequestValid(bannerBid)).to.be.false;
+ bannerBid.mediaTypes.banner.sizes = [];
+ expect(spec.isBidRequestValid(bannerBid)).to.be.false;
});
});
describe('native bidRequest', function () {
it('Should return true when correct native bid is passed', function () {
const nativeBid = createNativeBid();
- expect(spec.isBidRequestValid(nativeBid)).to.be.true;
+ const nativeLegacyBid = createNativeLegacyBid();
+ expect(spec.isBidRequestValid(nativeBid)).to.be.true && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.true;
});
it('Should return false when native is not an object', function () {
const nativeBid = createNativeBid();
- nativeBid.mediaTypes.native = 30;
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
+ const nativeLegacyBid = createNativeLegacyBid();
+ nativeBid.mediaTypes.native = nativeLegacyBid.mediaTypes.native = 30;
+ expect(spec.isBidRequestValid(nativeBid)).to.be.false && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.false;
});
- it('Should return false when native.ortb is not an object', function () {
+ it('Should return false when native.ortb if defined but it isn\'t an object', function () {
const nativeBid = createNativeBid();
nativeBid.mediaTypes.native.ortb = 30 || 'string';
expect(spec.isBidRequestValid(nativeBid)).to.be.false;
});
it('Should return false when native.ortb.assets is not an array', function () {
const nativeBid = createNativeBid();
- nativeBid.mediaTypes.native.ortb.assets = 30;
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
+ const nativeLegacyBid = createNativeLegacyBid();
+ nativeBid.mediaTypes.native.ortb.assets = nativeLegacyBid.mediaTypes.native.ortb.assets = 30;
+ expect(spec.isBidRequestValid(nativeBid)).to.be.false && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.false;
});
it('Should return false when native.ortb.assets is an empty array', function () {
const nativeBid = createNativeBid();
- nativeBid.mediaTypes.native.ortb.assets = [];
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
+ const nativeLegacyBid = createNativeLegacyBid();
+ nativeBid.mediaTypes.native.ortb.assets = nativeLegacyBid.mediaTypes.native.ortb.assets = [];
+ expect(spec.isBidRequestValid(nativeBid)).to.be.false && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] doesnt have \'id\'', function () {
const nativeBid = createNativeBid();
+ const nativeLegacyBid = createNativeLegacyBid();
Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[0], 'id');
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
+ Reflect.deleteProperty(nativeLegacyBid.mediaTypes.native.ortb.assets[0], 'id');
+ expect(spec.isBidRequestValid(nativeBid)).to.be.false && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] doesnt have any of \'title\', \'img\', \'data\' and \'video\' properties', function () {
const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[0], 'title');
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
+ const nativeLegacyBid = createNativeLegacyBid();
+ const titleIndex = nativeBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.title);
+ const legacyTitleIndex = nativeLegacyBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.title);
+ Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[titleIndex], 'title');
+ Reflect.deleteProperty(nativeLegacyBid.mediaTypes.native.ortb.assets[legacyTitleIndex], 'title');
+ expect(spec.isBidRequestValid(nativeBid)).to.be.false && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] have title, but doesnt have \'len\' property', function () {
const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[0].title, 'len');
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
- });
- it('Should return false when native.ortb.assets[i] is image but doesnt have \'wmin\' property', function () {
- const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[1].img, 'wmin');
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
- });
- it('Should return false when native.ortb.assets[i] is image but doesnt have \'hmin\' property', function () {
- const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[1].img, 'hmin');
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
+ const nativeLegacyBid = createNativeLegacyBid();
+ const titleIndex = nativeBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.title);
+ const legacyTitleIndex = nativeLegacyBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.title);
+ Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[titleIndex].title, 'len');
+ Reflect.deleteProperty(nativeLegacyBid.mediaTypes.native.ortb.assets[legacyTitleIndex].title, 'len');
+ expect(spec.isBidRequestValid(nativeBid)).to.be.false && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] is data but doesnt have \'type\' property', function () {
const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[2].data, 'type');
- expect(spec.isBidRequestValid(nativeBid)).to.be.false;
+ const nativeLegacyBid = createNativeLegacyBid();
+ const dataIndex = nativeBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.data);
+ Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[dataIndex].data, 'type');
+ Reflect.deleteProperty(nativeLegacyBid.mediaTypes.native.ortb.assets[dataIndex].data, 'type');
+ expect(spec.isBidRequestValid(nativeBid)).to.be.false && expect(spec.isBidRequestValid(nativeLegacyBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] is video but doesnt have \'mimes\' property', function () {
const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[3].video, 'mimes');
+ const videoIndex = nativeBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.video);
+ Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[videoIndex].video, 'mimes');
expect(spec.isBidRequestValid(nativeBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] is video but doesnt have \'minduration\' property', function () {
const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[3].video, 'minduration');
+ const videoIndex = nativeBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.video);
+ Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[videoIndex].video, 'minduration');
expect(spec.isBidRequestValid(nativeBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] is video but doesnt have \'maxduration\' property', function () {
const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[3].video, 'maxduration');
+ const videoIndex = nativeBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.video);
+ Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[videoIndex].video, 'maxduration');
expect(spec.isBidRequestValid(nativeBid)).to.be.false;
});
it('Should return false when native.ortb.assets[i] is video but doesnt have \'protocols\' property', function () {
const nativeBid = createNativeBid();
- Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[3].video, 'protocols');
+ const videoIndex = nativeBid.mediaTypes.native.ortb.assets.findIndex(asset => asset.video);
+ Reflect.deleteProperty(nativeBid.mediaTypes.native.ortb.assets[videoIndex].video, 'protocols');
expect(spec.isBidRequestValid(nativeBid)).to.be.false;
});
it('Should return false when native.ortb.eventtrackers is not an array', function () {
@@ -324,7 +386,7 @@ describe('onetag', function () {
describe('buildRequests', function () {
let serverRequest, data;
before(() => {
- serverRequest = spec.buildRequests([bannerBid, instreamVideoBid, nativeBid]);
+ serverRequest = spec.buildRequests([bannerBid, instreamVideoBid, nativeBid, nativeLegacyBid]);
data = JSON.parse(serverRequest.data);
});
@@ -387,6 +449,21 @@ describe('onetag', function () {
'type',
'priceFloors'
);
+ } else if (hasTypeNative(bid)) {
+ expect(bid).to.have.all.keys(
+ 'adUnitCode',
+ 'auctionId',
+ 'bidId',
+ 'bidderRequestId',
+ 'pubId',
+ 'ortb2Imp',
+ 'transactionId',
+ 'mediaTypeInfo',
+ 'sizes',
+ 'type',
+ 'priceFloors'
+ ) &&
+ expect(bid.mediaTypeInfo).to.have.key('ortb');
} else if (isValid(BANNER, bid)) {
expect(bid).to.have.all.keys(
'adUnitCode',