From f9fe687903079b73e78fe406416ca6040766bab8 Mon Sep 17 00:00:00 2001 From: Cameron Hotchkies Date: Tue, 30 Jan 2018 13:59:37 -0800 Subject: [PATCH 1/4] RockYou Adapter: Updated to support size coming from the mediaTypes object, multiple AdUnit support --- modules/rockyouBidAdapter.js | 102 +++++++++++--------- modules/rockyouBidAdapter.md | 4 +- test/spec/modules/rockyouBidAdapter_spec.js | 87 ++++++++++++----- 3 files changed, 119 insertions(+), 74 deletions(-) diff --git a/modules/rockyouBidAdapter.js b/modules/rockyouBidAdapter.js index 975756d18bc..5c40020f981 100644 --- a/modules/rockyouBidAdapter.js +++ b/modules/rockyouBidAdapter.js @@ -8,7 +8,7 @@ const BIDDER_CODE = 'rockyou'; const BASE_REQUEST_PATH = 'https://tas.rockyou.net/servlet/rotator/'; const IFRAME_SYNC_URL = 'https://prebid.tex-sync.rockyou.net/usersync2/tas'; const VAST_PLAYER_LOCATION = 'https://rya-static.rockyou.com/rya/js/PreBidPlayer.js'; -export const ROTATION_ZONE = 'openrtbprod'; +export const ROTATION_ZONE = 'prod'; let isBidRequestValid = (bid) => { return !!bid.params && !!bid.params.placementId; @@ -52,17 +52,27 @@ let extractValidSize = (bidRequest) => { let width = null; let height = null; - if (!utils.isEmpty(bidRequest.sizes)) { - // Ensure the size array is normalized - let conformingSize = utils.parseSizesInput(bidRequest.sizes); + let requestedSizes = []; + let mediaTypes = bidRequest.mediaTypes; + if (mediaTypes && ((mediaTypes.banner && mediaTypes.banner.sizes) || (mediaTypes.video && mediaTypes.video.playerSize))) { + if (mediaTypes.banner) { + requestedSizes = mediaTypes.banner.sizes; + } else { + requestedSizes = [mediaTypes.video.playerSize]; + } + } else if (!utils.isEmpty(bidRequest.sizes)) { + requestedSizes = bidRequest.sizes + } - if (!utils.isEmpty(conformingSize) && conformingSize[0] != null) { - // Currently only the first size is utilized - let splitSizes = conformingSize[0].split('x'); + // Ensure the size array is normalized + let conformingSize = utils.parseSizesInput(requestedSizes); - width = parseInt(splitSizes[0]); - height = parseInt(splitSizes[1]); - } + if (!utils.isEmpty(conformingSize) && conformingSize[0] != null) { + // Currently only the first size is utilized + let splitSizes = conformingSize[0].split('x'); + + width = parseInt(splitSizes[0]); + height = parseInt(splitSizes[1]); } return { @@ -109,22 +119,14 @@ let generateImpBody = (bidRequest) => { }; } -let generatePayload = (bidRequests) => { +let generatePayload = (bidRequest) => { // Generate the expected OpenRTB payload - let rootBidRequest = bidRequests[0]; - - let index = 1; - bidRequests.forEach((bidRequest) => { - bidRequest.index = index; - index += 1; - }) - let payload = { - id: determineOptimalRequestId(rootBidRequest), - site: buildSiteComponent(rootBidRequest), - device: buildDeviceComponent(rootBidRequest), - imp: bidRequests.map(generateImpBody) + id: determineOptimalRequestId(bidRequest), + site: buildSiteComponent(bidRequest), + device: buildDeviceComponent(bidRequest), + imp: [generateImpBody(bidRequest)] }; return JSON.stringify(payload); @@ -165,37 +167,41 @@ let buildRequests = (validBidRequests, requestRoot) => { let adUnitCode = null; let rendererOverride = null; + let results = []; // Due to the nature of how URLs are generated, there must // be at least one bid request present for this to function // correctly if (!utils.isEmpty(validBidRequests)) { - let headBidRequest = validBidRequests[0]; - - let serverLocations = overridableProperties(headBidRequest); - - // requestUrl is the full endpoint w/ relevant adspot paramters - let placementId = determineOptimalPlacementId(headBidRequest); - requestUrl = `${serverLocations.baseRequestPath}${placementId}/0/vo?z=${serverLocations.rotationZone}`; - - // requestPayload is the POST body JSON for the OpenRtb request - requestPayload = generatePayload(validBidRequests); - - mediaTypes = headBidRequest.mediaTypes; - adUnitCode = headBidRequest.adUnitCode; - rendererOverride = headBidRequest.rendererOverride; + results = validBidRequests.map( + bidRequest => { + let serverLocations = overridableProperties(bidRequest); + + // requestUrl is the full endpoint w/ relevant adspot paramters + let placementId = determineOptimalPlacementId(bidRequest); + requestUrl = `${serverLocations.baseRequestPath}${placementId}/0/vo?z=${serverLocations.rotationZone}`; + + // requestPayload is the POST body JSON for the OpenRtb request + requestPayload = generatePayload(bidRequest); + + mediaTypes = bidRequest.mediaTypes; + adUnitCode = bidRequest.adUnitCode; + rendererOverride = bidRequest.rendererOverride; + + return { + method: requestType, + type: requestType, + url: requestUrl, + data: requestPayload, + mediaTypes, + requestId: requestRoot.bidderRequestId, + adUnitCode, + rendererOverride + }; + } + ); } - const result = { - method: requestType, - type: requestType, - url: requestUrl, - data: requestPayload, - mediaTypes, - requestId: requestRoot.bidderRequestId, - adUnitCode, - rendererOverride - }; - return result; + return results; }; let outstreamRender = (bid) => { diff --git a/modules/rockyouBidAdapter.md b/modules/rockyouBidAdapter.md index 8cc9ba371d7..a7b15abc1bb 100644 --- a/modules/rockyouBidAdapter.md +++ b/modules/rockyouBidAdapter.md @@ -30,7 +30,7 @@ var adUnits = [ bids: [{ bidder: 'rockyou', params: { - placementId: '4322' + placementId: '4954' } }] }, @@ -49,7 +49,7 @@ var adUnits = [ bids: [{ bidder: 'rockyou', params: { - placementId: '4307' + placementId: '4957' } }] } diff --git a/test/spec/modules/rockyouBidAdapter_spec.js b/test/spec/modules/rockyouBidAdapter_spec.js index 8b38a333bca..7c06c41485c 100644 --- a/test/spec/modules/rockyouBidAdapter_spec.js +++ b/test/spec/modules/rockyouBidAdapter_spec.js @@ -33,9 +33,14 @@ describe('RockYouAdapter', () => { }, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'sizes': [[320, 50], [300, 250], [300, 600]], + 'sizes': [[999, 888]], 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757' + 'auctionId': '18fd8b8b0bd757', + 'mediaTypes': { + banner: { + 'sizes': [[320, 50], [300, 250], [300, 600]] + } + } }; it('successfully generates a URL', () => { @@ -49,9 +54,10 @@ describe('RockYouAdapter', () => { } ]; - let result = spec.buildRequests(bidRequests, { + let results = spec.buildRequests(bidRequests, { bidderRequestId: 'sample' }); + let result = results.pop(); expect(result.url).to.not.be.undefined; expect(result.url).to.not.be.null; @@ -66,9 +72,10 @@ describe('RockYouAdapter', () => { sampleBidRequest ]; - let result = spec.buildRequests(bidRequests, { + let results = spec.buildRequests(bidRequests, { bidderRequestId: 'sample' }); + let result = results.pop(); // Double encoded JSON let payload = JSON.parse(result.data); @@ -82,9 +89,10 @@ describe('RockYouAdapter', () => { sampleBidRequest ]; - let result = spec.buildRequests(bidRequests, { + let results = spec.buildRequests(bidRequests, { bidderRequestId: 'sample' }); + let result = results.pop(); // Double encoded JSON let payload = JSON.parse(result.data); @@ -95,33 +103,57 @@ describe('RockYouAdapter', () => { expect(userData).to.not.be.null; }); - it('generates multiple imp bodies', () => { + it('generates multiple requests with single imp bodies', () => { + const SECOND_PLACEMENT_ID = 'YYYPLACEMENTIDYYY'; + let firstBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); + let secondBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); + secondBidRequest.params.placementId = SECOND_PLACEMENT_ID; + let bidRequests = [ - sampleBidRequest, - sampleBidRequest + firstBidRequest, + secondBidRequest ]; - let result = spec.buildRequests(bidRequests, { + let results = spec.buildRequests(bidRequests, { bidderRequestId: 'sample' }); + expect(results instanceof Array).to.be.true; + expect(results.length).to.equal(2); + + let firstRequest = results[0]; + // Double encoded JSON - let payload = JSON.parse(result.data); + let firstPayload = JSON.parse(firstRequest.data); - expect(payload).to.not.be.null; - expect(payload.imp).to.not.be.null; - expect(payload.imp.length).to.equal(2); + expect(firstPayload).to.not.be.null; + expect(firstPayload.imp).to.not.be.null; + expect(firstPayload.imp.length).to.equal(1); + + expect(firstRequest.url).to.not.be.null; + expect(firstRequest.url.indexOf('ZZZPLACEMENTZZZ')).to.be.gt(0); + + let secondRequest = results[1]; + + // Double encoded JSON + let secondPayload = JSON.parse(secondRequest.data); + + expect(secondPayload).to.not.be.null; + expect(secondPayload.imp).to.not.be.null; + expect(secondPayload.imp.length).to.equal(1); + + expect(secondRequest.url).to.not.be.null; + expect(secondRequest.url.indexOf(SECOND_PLACEMENT_ID)).to.be.gt(0); }); it('generates a banner request as expected', () => { // clone the sample for stability let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - localBidRequest.mediaTypes = { banner: {} }; - - let result = spec.buildRequests([localBidRequest], { + let results = spec.buildRequests([localBidRequest], { bidderRequestId: 'sample' }); + let result = results.pop(); // Double encoded JSON let payload = JSON.parse(result.data); @@ -146,9 +178,10 @@ describe('RockYouAdapter', () => { localBidRequest.sizes = [320, 50]; localBidRequest.mediaTypes = { banner: {} }; - let result = spec.buildRequests([localBidRequest], { + let results = spec.buildRequests([localBidRequest], { bidderRequestId: 'sample' }); + let result = results.pop(); // Double encoded JSON let payload = JSON.parse(result.data); @@ -171,11 +204,13 @@ describe('RockYouAdapter', () => { // clone the sample for stability let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); localBidRequest.sizes = ['x', 'w']; - localBidRequest.mediaTypes = { banner: {} }; - let result = spec.buildRequests([localBidRequest], { + localBidRequest.mediaTypes = { banner: { sizes: ['y', 'z']} }; + + let results = spec.buildRequests([localBidRequest], { bidderRequestId: 'sample' }); + let result = results.pop(); // Double encoded JSON let payload = JSON.parse(result.data); @@ -198,11 +233,14 @@ describe('RockYouAdapter', () => { // clone the sample for stability let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - localBidRequest.mediaTypes = { video: {} }; + localBidRequest.mediaTypes = { video: { + playerSize: [326, 56] + } }; - let result = spec.buildRequests([localBidRequest], { + let results = spec.buildRequests([localBidRequest], { bidderRequestId: 'sample' }); + let result = results.pop(); // Double encoded JSON let payload = JSON.parse(result.data); @@ -217,8 +255,8 @@ describe('RockYouAdapter', () => { let videoData = firstImp.video; - expect(videoData.w).to.equal(320); - expect(videoData.h).to.equal(50); + expect(videoData.w).to.equal(326); + expect(videoData.h).to.equal(56); }); it('propagates the mediaTypes object in the built request', () => { @@ -226,9 +264,10 @@ describe('RockYouAdapter', () => { localBidRequest.mediaTypes = { video: {} }; - let result = spec.buildRequests([localBidRequest], { + let results = spec.buildRequests([localBidRequest], { bidderRequestId: 'sample' }); + let result = results.pop(); let mediaTypes = result.mediaTypes; From c0b11f4698d28a28240d9bdc73d4a0cce110d5d0 Mon Sep 17 00:00:00 2001 From: Cameron Hotchkies Date: Tue, 30 Jan 2018 14:08:24 -0800 Subject: [PATCH 2/4] RockYou Adapter: Readme updates --- modules/rockyouBidAdapter.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/rockyouBidAdapter.md b/modules/rockyouBidAdapter.md index a7b15abc1bb..1c6d2708b99 100644 --- a/modules/rockyouBidAdapter.md +++ b/modules/rockyouBidAdapter.md @@ -24,9 +24,12 @@ var adUnits = [ // Banner adUnit { code: 'banner-div', - sizes: [[720, 480]], + mediaTypes: { + banner: { + sizes: [[720, 480]] + } + }, - // Replace this object to test a new Adapter! bids: [{ bidder: 'rockyou', params: { @@ -38,12 +41,10 @@ var adUnits = [ // Video (outstream) { code: 'video-outstream', - sizes: [[720, 480]], - - mediaType: 'video', mediaTypes: { video: { - context: 'outstream' + context: 'outstream', + playerSize: [720, 480] } }, bids: [{ From 17a4b6e41a4b9fd613238f7b212cfa52848bf0e3 Mon Sep 17 00:00:00 2001 From: Cameron Hotchkies Date: Wed, 31 Jan 2018 14:39:17 -0800 Subject: [PATCH 3/4] RockYou Adapter: explicitly pass request.bidId in the response object --- modules/rockyouBidAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/rockyouBidAdapter.js b/modules/rockyouBidAdapter.js index 5c40020f981..497e85d84d0 100644 --- a/modules/rockyouBidAdapter.js +++ b/modules/rockyouBidAdapter.js @@ -194,6 +194,7 @@ let buildRequests = (validBidRequests, requestRoot) => { data: requestPayload, mediaTypes, requestId: requestRoot.bidderRequestId, + bidId: bidRequest.bidId, adUnitCode, rendererOverride }; @@ -314,7 +315,7 @@ let interpretResponse = (serverResponse, request) => { } let response = { - requestId: responseBody.id, + requestId: request.bidId, cpm: bid.price, width: bidWidth, height: bidHeight, From df6092861d042cb4489e3fb3aebdbdf492f4888a Mon Sep 17 00:00:00 2001 From: Cameron Hotchkies Date: Thu, 22 Feb 2018 11:09:17 -0800 Subject: [PATCH 4/4] RockYou Adapter: Updated sync URL --- modules/rockyouBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/rockyouBidAdapter.js b/modules/rockyouBidAdapter.js index 497e85d84d0..0748d6842a6 100644 --- a/modules/rockyouBidAdapter.js +++ b/modules/rockyouBidAdapter.js @@ -6,7 +6,7 @@ import { registerBidder } from 'src/adapters/bidderFactory'; const BIDDER_CODE = 'rockyou'; const BASE_REQUEST_PATH = 'https://tas.rockyou.net/servlet/rotator/'; -const IFRAME_SYNC_URL = 'https://prebid.tex-sync.rockyou.net/usersync2/tas'; +const IFRAME_SYNC_URL = 'https://prebid.tas-sync.rockyou.net/usersync2/prebid'; const VAST_PLAYER_LOCATION = 'https://rya-static.rockyou.com/rya/js/PreBidPlayer.js'; export const ROTATION_ZONE = 'prod';