diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js
index 3be919453a3..6970eefeac2 100644
--- a/modules/ixBidAdapter.js
+++ b/modules/ixBidAdapter.js
@@ -2,7 +2,6 @@ import * as utils from '../src/utils.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import { config } from '../src/config.js';
import find from 'core-js-pure/features/array/find.js';
-import isInteger from 'core-js-pure/features/number/is-integer.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
const BIDDER_CODE = 'ix';
@@ -206,6 +205,8 @@ function _applyFloor(bid, imp, mediaType) {
*/
function parseBid(rawBid, currency, bidRequest) {
const bid = {};
+ const isValidExpiry = !!((utils.deepAccess(rawBid, 'exp') && utils.isInteger(rawBid.exp)));
+ const dealID = utils.deepAccess(rawBid, 'dealid') || utils.deepAccess(rawBid, 'ext.dealid');
if (PRICE_TO_DOLLAR_FACTOR.hasOwnProperty(currency)) {
bid.cpm = rawBid.price / PRICE_TO_DOLLAR_FACTOR[currency];
@@ -215,7 +216,10 @@ function parseBid(rawBid, currency, bidRequest) {
bid.requestId = rawBid.impid;
- bid.dealId = utils.deepAccess(rawBid, 'ext.dealid');
+ if (dealID) {
+ bid.dealId = dealID;
+ }
+
bid.netRevenue = NET_REVENUE;
bid.currency = currency;
bid.creativeId = rawBid.hasOwnProperty('crid') ? rawBid.crid : '-';
@@ -226,13 +230,13 @@ function parseBid(rawBid, currency, bidRequest) {
bid.width = bidRequest.video.w;
bid.height = bidRequest.video.h;
bid.mediaType = VIDEO;
- bid.ttl = VIDEO_TIME_TO_LIVE;
+ bid.ttl = isValidExpiry ? rawBid.exp : VIDEO_TIME_TO_LIVE;
} else {
bid.ad = rawBid.adm;
bid.width = rawBid.w;
bid.height = rawBid.h;
bid.mediaType = BANNER;
- bid.ttl = BANNER_TIME_TO_LIVE;
+ bid.ttl = isValidExpiry ? rawBid.exp : BANNER_TIME_TO_LIVE;
}
bid.meta = {};
@@ -253,7 +257,7 @@ function parseBid(rawBid, currency, bidRequest) {
* @return {boolean} True if this is a valid size format, and false otherwise.
*/
function isValidSize(size) {
- return Array.isArray(size) && size.length === 2 && isInteger(size[0]) && isInteger(size[1]);
+ return Array.isArray(size) && size.length === 2 && utils.isInteger(size[0]) && utils.isInteger(size[1]);
}
/**
@@ -385,7 +389,7 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
const r = {};
// Since bidderRequestId are the same for different bid request, just use the first one.
- r.id = validBidRequests[0].bidderRequestId;
+ r.id = validBidRequests[0].bidderRequestId.toString();
r.site = {};
r.ext = {};
@@ -452,6 +456,10 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
}
}
+ if (config.getConfig('coppa')) {
+ utils.deepSetValue(r, 'regs.coppa', 1);
+ }
+
const payload = {};
// Parse additional runtime configs.
diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js
index 50920965b60..c026dfd3efc 100644
--- a/test/spec/modules/ixBidAdapter_spec.js
+++ b/test/spec/modules/ixBidAdapter_spec.js
@@ -1221,7 +1221,7 @@ describe('IndexexchangeAdapter', function () {
});
describe('buildRequests', function () {
- const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0];
+ let request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0];
const requestUrl = request.url;
const requestMethod = request.method;
const query = request.data;
@@ -1254,6 +1254,7 @@ describe('IndexexchangeAdapter', function () {
it('payload should have correct format and value', function () {
const payload = JSON.parse(query.r);
expect(payload.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidderRequestId);
+ expect(payload.id).to.be.a('string');
expect(payload.site).to.exist;
expect(payload.site.page).to.equal(DEFAULT_OPTION.refererInfo.referer);
expect(payload.site.ref).to.equal(document.referrer);
@@ -1265,6 +1266,18 @@ describe('IndexexchangeAdapter', function () {
expect(payload.imp).to.have.lengthOf(2);
});
+ it('payload should have correct format and value for r.id when bidderRequestId is a number ', function () {
+ const bidWithIntId = utils.deepClone(DEFAULT_BANNER_VALID_BID);
+ bidWithIntId[0].bidderRequestId = 123456;
+
+ request = spec.buildRequests(bidWithIntId, DEFAULT_OPTION)[0];
+
+ const payload = JSON.parse(request.data.r);
+ expect(bidWithIntId[0].bidderRequestId).to.be.a('number');
+ expect(payload.id).to.equal(bidWithIntId[0].bidderRequestId.toString());
+ expect(payload.id).to.be.a('string');
+ });
+
it('payload should not include schain when not provided', function () {
const payload = JSON.parse(queryWithoutSchain.r);
expect(payload.source).to.not.exist; // source object currently only written for schain
@@ -1963,7 +1976,6 @@ describe('IndexexchangeAdapter', function () {
currency: 'USD',
ttl: 300,
netRevenue: true,
- dealId: undefined,
meta: {
networkId: 50,
brandId: 303325,
@@ -1989,7 +2001,6 @@ describe('IndexexchangeAdapter', function () {
currency: 'USD',
ttl: 300,
netRevenue: true,
- dealId: undefined,
meta: {
networkId: 50,
brandId: 303325,
@@ -2016,7 +2027,6 @@ describe('IndexexchangeAdapter', function () {
currency: 'USD',
ttl: 300,
netRevenue: true,
- dealId: undefined,
meta: {
networkId: 50,
brandId: 303325,
@@ -2043,7 +2053,6 @@ describe('IndexexchangeAdapter', function () {
currency: 'JPY',
ttl: 300,
netRevenue: true,
- dealId: undefined,
meta: {
networkId: 50,
brandId: 303325,
@@ -2056,9 +2065,38 @@ describe('IndexexchangeAdapter', function () {
expect(result[0]).to.deep.equal(expectedParse[0]);
});
- it('should set dealId correctly', function () {
+ it('should prioritize bid[].dealid over bid[].ext.dealid ', function () {
+ const bidResponse = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE);
+ bidResponse.seatbid[0].bid[0].ext.dealid = 'ext-deal';
+ bidResponse.seatbid[0].bid[0].dealid = 'outter-deal';
+ const expectedParse = [
+ {
+ requestId: '1a2b3c4d',
+ cpm: 1,
+ creativeId: '12345',
+ width: 300,
+ height: 250,
+ mediaType: 'banner',
+ ad: '',
+ currency: 'USD',
+ ttl: 300,
+ netRevenue: true,
+ dealId: 'outter-deal',
+ meta: {
+ networkId: 50,
+ brandId: 303325,
+ brandName: 'OECTA',
+ advertiserDomains: ['www.abc.com']
+ }
+ }
+ ];
+ const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA });
+
+ expect(result[0].dealId).to.equal(expectedParse[0].dealId);
+ });
+
+ it('should not set bid[].dealid if dealid is not present', function () {
const bidResponse = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE);
- bidResponse.seatbid[0].bid[0].ext.dealid = 'deal';
const expectedParse = [
{
requestId: '1a2b3c4d',
@@ -2071,7 +2109,6 @@ describe('IndexexchangeAdapter', function () {
currency: 'USD',
ttl: 300,
netRevenue: true,
- dealId: 'deal',
meta: {
networkId: 50,
brandId: 303325,
@@ -2084,6 +2121,34 @@ describe('IndexexchangeAdapter', function () {
expect(result[0]).to.deep.equal(expectedParse[0]);
});
+ it('should use set bid[].ext.dealid if bid[].dealid is not present', function () {
+ const bidResponse = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE);
+ bidResponse.seatbid[0].bid[0].ext.dealid = 'ext-deal';
+ const expectedParse = [
+ {
+ requestId: '1a2b3c4d',
+ cpm: 1,
+ creativeId: '12345',
+ width: 300,
+ height: 250,
+ mediaType: 'banner',
+ ad: '',
+ currency: 'USD',
+ ttl: 300,
+ dealId: 'ext-deal',
+ netRevenue: true,
+ meta: {
+ networkId: 50,
+ brandId: 303325,
+ brandName: 'OECTA',
+ advertiserDomains: ['www.abc.com']
+ }
+ }
+ ];
+ const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA });
+ expect(result[0].dealId).to.deep.equal(expectedParse[0].dealId);
+ });
+
it('should get correct bid response for video ad', function () {
const expectedParse = [
{
@@ -2096,7 +2161,6 @@ describe('IndexexchangeAdapter', function () {
currency: 'USD',
ttl: 3600,
netRevenue: true,
- dealId: undefined,
vastUrl: 'www.abcd.com/vast',
meta: {
networkId: 51,
@@ -2142,6 +2206,26 @@ describe('IndexexchangeAdapter', function () {
expect(requestWithoutreferInfo.site.page).to.equal(options.refererInfo.referer);
expect(validBidWithoutreferInfo[0].url).to.equal(IX_SECURE_ENDPOINT);
});
+
+ it('should set bid[].ttl to seatbid[].bid[].exp value from response', function () {
+ const BANNER_RESPONSE_WITH_EXP = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE);
+ const VIDEO_RESPONSE_WITH_EXP = utils.deepClone(DEFAULT_VIDEO_BID_RESPONSE);
+ VIDEO_RESPONSE_WITH_EXP.seatbid[0].bid[0].exp = 200;
+ BANNER_RESPONSE_WITH_EXP.seatbid[0].bid[0].exp = 100;
+ const bannerResult = spec.interpretResponse({ body: BANNER_RESPONSE_WITH_EXP }, { data: DEFAULT_BIDDER_REQUEST_DATA });
+ const videoResult = spec.interpretResponse({ body: VIDEO_RESPONSE_WITH_EXP }, { data: DEFAULT_BIDDER_REQUEST_DATA });
+
+ expect(bannerResult[0].ttl).to.equal(100);
+ expect(videoResult[0].ttl).to.equal(200);
+ });
+
+ it('should default bid[].ttl if seat[].bid[].exp is not in the resposne', function () {
+ const bannerResult = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA });
+ const videoResult = spec.interpretResponse({ body: DEFAULT_VIDEO_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA });
+
+ expect(bannerResult[0].ttl).to.equal(300);
+ expect(videoResult[0].ttl).to.equal(3600);
+ });
});
describe('bidrequest consent', function () {
@@ -2248,5 +2332,27 @@ describe('IndexexchangeAdapter', function () {
expect(utils.deepAccess(requestWithConsent, 'user.ext.consented_providers_settings')).to.not.exist;
expect(utils.deepAccess(requestWithConsent, 'user.ext.consent')).to.not.exist;
});
+
+ it('should set coppa to 1 in config when enabled', () => {
+ config.setConfig({ coppa: true })
+ const bid = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION);
+ const r = JSON.parse(bid[0].data.r);
+
+ expect(r.regs.coppa).to.equal(1);
+ });
+ it('should not set coppa in config when disabled', () => {
+ config.setConfig({ coppa: false })
+ const bid = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION);
+ const r = JSON.parse(bid[0].data.r);
+
+ expect(r.regs.coppa).to.be.undefined;
+ });
+ it('should not set coppa when not specified in config', () => {
+ config.resetConfig();
+ const bid = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION);
+ const r = JSON.parse(bid[0].data.r);
+
+ expect(r.regs.coppa).to.be.undefined;
+ });
});
});