Skip to content

Commit

Permalink
IX Bid Adapter: Adding support for IX Outstream Renderer (prebid#7390)
Browse files Browse the repository at this point in the history
* add ix renderer support

* add unit tests

* lint fix
  • Loading branch information
umakajan authored and Chris Pabst committed Jan 10, 2022
1 parent ee5a66c commit aedf25d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 19 deletions.
62 changes: 56 additions & 6 deletions modules/ixBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import find from 'core-js-pure/features/array/find.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { INSTREAM, OUTSTREAM } from '../src/video.js';
import includes from 'core-js-pure/features/array/includes.js';
import { Renderer } from '../src/Renderer.js';

const BIDDER_CODE = 'ix';
const ALIAS_BIDDER_CODE = 'roundel';
Expand All @@ -24,7 +25,7 @@ const PRICE_TO_DOLLAR_FACTOR = {
JPY: 1
};
const USER_SYNC_URL = 'https://js-sec.indexww.com/um/ixmatch.html';

const RENDERER_URL = 'https://js-sec.indexww.com/htv/video-player.js';
const FLOOR_SOURCE = { PBJS: 'p', IX: 'x' };
// determines which eids we send and the rtiPartner field in ext

Expand Down Expand Up @@ -267,6 +268,7 @@ function parseBid(rawBid, currency, bidRequest) {
bid.width = bidRequest.video.w;
bid.height = bidRequest.video.h;
bid.mediaType = VIDEO;
bid.mediaTypes = bidRequest.mediaTypes;
bid.ttl = isValidExpiry ? rawBid.exp : VIDEO_TIME_TO_LIVE;
} else {
bid.ad = rawBid.adm;
Expand Down Expand Up @@ -385,17 +387,22 @@ function isValidBidFloorParams(bidFloor, bidFloorCur) {
}

/**
* Finds the impression with the associated id.
* Get bid request object with the associated id.
*
* @param {*} id Id of the impression.
* @param {array} impressions List of impressions sent in the request.
* @return {object} The impression with the associated id.
*/
function getBidRequest(id, impressions) {
function getBidRequest(id, impressions, validBidRequests) {
if (!id) {
return;
}
return find(impressions, imp => imp.id === id);
const bidRequest = {
...find(validBidRequests, bid => bid.bidId === id),
...find(impressions, imp => imp.id === id)
}

return bidRequest;
}

/**
Expand Down Expand Up @@ -718,7 +725,8 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
requests.push({
method: 'GET',
url: baseUrl,
data: clonedPayload
data: clonedPayload,
validBidRequests
});

currentRequestSize = baseRequestSize;
Expand Down Expand Up @@ -930,6 +938,43 @@ function createMissingBannerImp(bid, imp, newSize) {
return newImp;
}

/**
* Initialize Outstream Renderer
* @param {Object} bid
*/
function outstreamRenderer (bid) {
bid.renderer.push(() => {
var config = {
width: bid.width,
height: bid.height,
timeout: 3000
};

window.IXOutstreamPlayer(bid.vastUrl, bid.adUnitCode, config);
});
}

/**
* Create Outstream Renderer
* @param {string} id
* @returns {Renderer}
*/
function createRenderer (id) {
const renderer = Renderer.install({
id: id,
url: RENDERER_URL,
loaded: false
});

try {
renderer.setRender(outstreamRenderer);
} catch (err) {
utils.logWarn('Prebid Error calling setRender on renderer', err);
}

return renderer;
}

export const spec = {

code: BIDDER_CODE,
Expand Down Expand Up @@ -1108,8 +1153,13 @@ export const spec = {
let requestBid = JSON.parse(bidderRequest.data.r);

for (let j = 0; j < innerBids.length; j++) {
const bidRequest = getBidRequest(innerBids[j].impid, requestBid.imp);
const bidRequest = getBidRequest(innerBids[j].impid, requestBid.imp, bidderRequest.validBidRequests);
bid = parseBid(innerBids[j], responseBody.cur, bidRequest);

if (!utils.deepAccess(bid, 'mediaTypes.video.renderer') && utils.deepAccess(bid, 'mediaTypes.video.context') === 'outstream') {
bid.mediaTypes.video.renderer = createRenderer(innerBids[j].bidId);
}

bids.push(bid);
}
}
Expand Down
40 changes: 27 additions & 13 deletions test/spec/modules/ixBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ describe('IndexexchangeAdapter', function () {
});

describe('First party data', function () {
afterEach(function() {
afterEach(function () {
config.setConfig({
ortb2: {}
})
Expand Down Expand Up @@ -2129,7 +2129,7 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
expect(result[0]).to.deep.equal(expectedParse[0]);
});

Expand All @@ -2153,7 +2153,7 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE_WITHOUT_ADOMAIN }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE_WITHOUT_ADOMAIN }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
expect(result[0]).to.deep.equal(expectedParse[0]);
});

Expand All @@ -2180,7 +2180,7 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
});

it('should set Japanese price correctly', function () {
Expand All @@ -2206,7 +2206,7 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
expect(result[0]).to.deep.equal(expectedParse[0]);
});

Expand Down Expand Up @@ -2235,7 +2235,7 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });

expect(result[0].dealId).to.equal(expectedParse[0].dealId);
});
Expand All @@ -2262,7 +2262,7 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
expect(result[0]).to.deep.equal(expectedParse[0]);
});

Expand Down Expand Up @@ -2290,7 +2290,7 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
expect(result[0].dealId).to.deep.equal(expectedParse[0].dealId);
});

Expand All @@ -2301,6 +2301,17 @@ describe('IndexexchangeAdapter', function () {
cpm: 1.1,
creativeId: '12346',
mediaType: 'video',
mediaTypes: {
video: {
context: 'instream',
playerSize: [
[
400,
100
]
]
}
},
width: 640,
height: 480,
currency: 'USD',
Expand All @@ -2315,7 +2326,10 @@ describe('IndexexchangeAdapter', function () {
}
}
];
const result = spec.interpretResponse({ body: DEFAULT_VIDEO_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA });
const result = spec.interpretResponse({ body: DEFAULT_VIDEO_BID_RESPONSE }, {
data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: ONE_VIDEO
});

expect(result[0]).to.deep.equal(expectedParse[0]);
});

Expand Down Expand Up @@ -2357,16 +2371,16 @@ describe('IndexexchangeAdapter', function () {
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 });
const bannerResult = spec.interpretResponse({ body: BANNER_RESPONSE_WITH_EXP }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
const videoResult = spec.interpretResponse({ body: VIDEO_RESPONSE_WITH_EXP }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });

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 });
const bannerResult = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });
const videoResult = spec.interpretResponse({ body: DEFAULT_VIDEO_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA, validBidRequests: [] });

expect(bannerResult[0].ttl).to.equal(300);
expect(videoResult[0].ttl).to.equal(3600);
Expand Down

0 comments on commit aedf25d

Please sign in to comment.