From 418baed6193f8309d4db627a67e24ec67c9ba525 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Thu, 12 Jul 2018 16:09:23 -0400 Subject: [PATCH 01/11] initial commit --- integrationExamples/gpt/pbjs_example_gpt.html | 6 + modules/zedoBidAdapter.js | 188 ++++++++++++++++++ modules/zedoBidAdapter.md | 27 +++ test/spec/modules/zedoBidAdapter_spec.js | 167 ++++++++++++++++ 4 files changed, 388 insertions(+) create mode 100644 modules/zedoBidAdapter.js create mode 100644 modules/zedoBidAdapter.md create mode 100644 test/spec/modules/zedoBidAdapter_spec.js diff --git a/integrationExamples/gpt/pbjs_example_gpt.html b/integrationExamples/gpt/pbjs_example_gpt.html index e54a604e281..0cc7aca7cc4 100644 --- a/integrationExamples/gpt/pbjs_example_gpt.html +++ b/integrationExamples/gpt/pbjs_example_gpt.html @@ -288,6 +288,12 @@ pubId: 50357, //REQUIRED host: 'dsp-staging.adkernel.com' //OPTIONAL } + }, + { + bidder: 'zedo', + params: { + channelCode: 2264002816, //REQUIRED + } } ] }, { diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js new file mode 100644 index 00000000000..966cc03b45f --- /dev/null +++ b/modules/zedoBidAdapter.js @@ -0,0 +1,188 @@ +import * as utils from 'src/utils'; +import { registerBidder } from 'src/adapters/bidderFactory'; +import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes'; +import find from 'core-js/library/fn/array/find'; + +const BIDDER_CODE = 'zedo'; +const URL = '//z2.zedo.com/asw/fmb.json'; +const SECURE_URL = '//z2.zedo.com/asw/fmb.json'; +const SIZE = { + '300x250': 9, + '160x600': 88, + '640x480': 85 // TODO check for 1x1 +}; + +export const spec = { + code: BIDDER_CODE, + aliases: [], + supportedMediaTypes: [BANNER, VIDEO], + + /** + * Determines whether or not the given bid request is valid. + * + * @param {object} bid The bid to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + return !!(bid.params && bid.params.channelCode); + }, + + /** + * Make a server request from the list of BidRequests. + * + * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function (bidRequests) { + let data = { + placements: [] + }; + bidRequests.map(bidRequest => { + let channelCode = parseInt(bidRequest.params.channelCode); + let network = parseInt(channelCode / 1000000); + let channel = channelCode % 1000000; + let dims = getSizes(bidRequest.sizes); + let placement = { + id: bidRequest.bidId, + network: network, + channel: channel, + width: dims[0][0] ? dims[0][0] : 468, + height: dims[0][1] ? dims[0][1] : 60, + dimension: dims[0][2] ? dims[0][2] : 9, // TODO : check default + version: '$prebid.version$', + transactionId: bidRequest.transactionId + } + const videoMediaType = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`); + if (bidRequest.mediaType === VIDEO || videoMediaType) { + placement['renderers'] = [{ + 'name': 'Inarticle' + }] + } else { + placement['renderers'] = [{ + 'name': 'display' + }] + } + data['placements'].push(placement); + }); + let reqUrl = utils.getTopWindowLocation().protocol === 'http:' ? URL : SECURE_URL; + return { + method: 'GET', + url: reqUrl, + data: 'g=' + JSON.stringify(data) + } + }, + + /** + * Unpack the response from the server into a list of bids. + * + * @param {*} serverResponse A successful response from the server. + * @return {Bid[]} An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, request) { + serverResponse = serverResponse.body; + const bids = []; + if (!serverResponse || serverResponse.error) { + let errorMessage = `in response for ${request.bidderCode} adapter`; + if (serverResponse && serverResponse.error) { errorMessage += `: ${serverResponse.error}`; } + utils.logError(errorMessage); + return bids; + } + + if (serverResponse.ad) { + serverResponse.ad.forEach(ad => { + const creativeBid = getCreative(ad); + if (creativeBid) { + if (parseInt(creativeBid.cpm) !== 0) { + const bid = newBid(ad, creativeBid, request); + bid.mediaType = parseMediaType(creativeBid); + bids.push(bid); + } + } + }); + } + return bids; + }, + + getUserSyncs: function (syncOptions) { + if (syncOptions.iframeEnabled) { + return [{ + // TODO implement user sync + }]; + } + } +}; + +function getCreative(ad) { + return ad && ad.creatives && ad.creatives.length && find(ad.creatives, creative => creative.adId); +} +/** + * Unpack the Server's Bid into a Prebid-compatible one. + * @param serverBid + * @param rtbBid + * @param bidderRequest + * @return Bid + */ +function newBid(serverBid, creativeBid, bidderRequest) { + const bid = { + requestId: serverBid.slotId, + cpm: creativeBid.cpm, + creativeId: creativeBid.adId, + dealId: 99999999, + currency: 'USD', + netRevenue: true, + ttl: 300 + }; + + if (creativeBid.creativeDetails.type === 'Vast') { + Object.assign(bid, { + width: creativeBid.width, + height: creativeBid.height, + vastXml: creativeBid.creativeDetails.adContent, + ttl: 3600 + }); + } else { + Object.assign(bid, { + width: creativeBid.width, + height: creativeBid.height, + ad: creativeBid.creativeDetails.adContent + }); + } + + return bid; +} +/* Turn bid request sizes into ut-compatible format */ +function getSizes(requestSizes) { + let dims = []; + let sizeObj = {}; + + if (utils.isArray(requestSizes) && requestSizes.length === 2 && + !utils.isArray(requestSizes[0])) { + sizeObj.width = parseInt(requestSizes[0], 10); + sizeObj.height = parseInt(requestSizes[1], 10); + let dim = SIZE[sizeObj.width + 'x' + sizeObj.height]; + if (dim) { + dims.push([sizeObj.width, sizeObj.height, dim]); + } + } else if (typeof requestSizes === 'object') { + for (let i = 0; i < requestSizes.length; i++) { + let size = requestSizes[i]; + sizeObj = {}; + sizeObj.width = parseInt(size[0], 10); + sizeObj.height = parseInt(size[1], 10); + let dim = SIZE[sizeObj.width + 'x' + sizeObj.height]; + dims.push([sizeObj.width, sizeObj.height, dim]); + } + } + return dims; +} + +function parseMediaType(rtbBid) { + const adType = rtbBid.ad_type; + if (adType === VIDEO) { + return VIDEO; + } else { + return BANNER; + } +} + +registerBidder(spec); diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md new file mode 100644 index 00000000000..203fc0b9c7e --- /dev/null +++ b/modules/zedoBidAdapter.md @@ -0,0 +1,27 @@ +# Overview + +Module Name: ZEDO Bidder Adapter +Module Type: Bidder Adapter +Maintainer: + +# Description + +Module that connects to ZEDO's demand sources. + +# Test Parameters +``` + var adUnits = [ + { + code: 'banner-ad-div', + sizes: [[300, 250], [728, 90]], + bids: [ + { + bidder: 'zedo', + params: { + code: 2264002816 + } + } + ] + } + ]; +``` diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js new file mode 100644 index 00000000000..05a75ab5d0e --- /dev/null +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -0,0 +1,167 @@ +import { expect } from 'chai'; +import { spec } from 'modules/zedoBidAdapter'; + +describe('The ZEDO bidding adapter', () => { + describe('isBidRequestValid', () => { + it('should return false when given an invalid bid', () => { + const bid = { + bidder: 'zedo', + }; + const isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equal(false); + }); + + it('should return true when given a channelcode bid', () => { + const bid = { + bidder: 'zedo', + params: { + channelCode: 20000000, + }, + }; + const isValid = spec.isBidRequestValid(bid); + expect(isValid).to.equal(true); + }); + }); + + describe('buildRequests', () => { + const bidderRequest = { + timeout: 3000, + }; + + it('should properly build a channelCode request for banner', () => { + const bidRequests = [ + { + bidder: 'zedo', + adUnitCode: 'p12345', + transactionId: '12345667', + sizes: [[300, 250]], + params: { + channelCode: 20000000, + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); + expect(request.method).to.equal('GET'); + const zedoRequest = request.data; + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":250,"dimension":9,"version":"$prebid.version$","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); + }); + + it('should properly build a channelCode request for video', () => { + const bidRequests = [ + { + bidder: 'zedo', + adUnitCode: 'p12345', + transactionId: '12345667', + sizes: [640, 480], + mediaTypes: { + video: { + context: 'instream', + }, + }, + params: { + channelCode: 20000000, + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); + expect(request.method).to.equal('GET'); + const zedoRequest = request.data; + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); + }); + }); + describe('interpretResponse', () => { + it('should return an empty array when there is bid response', () => { + const response = {}; + const request = { bidRequests: [] }; + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(0); + }); + + it('should properly parse a bid response with no valid creative', () => { + const response = { + body: { + ad: [ + { + 'slotId': 'ad1d762', + 'network': '2000', + 'creatives': [ + { + 'adId': '12345', + 'height': '600', + 'width': '160', + 'isFoc': true, + 'creativeDetails': { + 'type': 'StdBanner', + 'adContent': { + 'focImage': { + 'url': 'https://c13.zedo.com/OzoDB/0/0/0/blank.gif', + 'target': '_blank', + } + } + }, + 'cpm': '0' + } + ] + } + ] + } + }; + const request = { + bidRequests: [{ + bidder: 'zedo', + adUnitCode: 'p12345', + bidId: 'test-bidId', + params: { + channelCode: 2000000, + } + }] + }; + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(0); + }); + + it('should properly parse a bid response with valid creative', () => { + const response = { + body: { + ad: [ + { + 'slotId': 'ad1d762', + 'network': '2000', + 'creatives': [ + { + 'adId': '12345', + 'height': '600', + 'width': '160', + 'isFoc': true, + 'creativeDetails': { + 'type': 'StdBanner', + 'adContent': '' + }, + 'cpm': '1.2' + } + ] + } + ] + } + }; + const request = { + bidRequests: [{ + bidder: 'zedo', + adUnitCode: 'test-requestId', + bidId: 'test-bidId', + params: { + zoneId: 123, + }, + }] + }; + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(1); + expect(bids[0].requestId).to.equal('ad1d762'); + expect(bids[0].cpm).to.equal('1.2'); + expect(bids[0].width).to.equal('160'); + expect(bids[0].height).to.equal('600'); + }); + }); +}); From 4381ccddf158260f86536c8d531bd4b22660f4d9 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Fri, 13 Jul 2018 17:14:30 -0400 Subject: [PATCH 02/11] updated contact and tag details --- modules/zedoBidAdapter.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md index 203fc0b9c7e..259c4c02dee 100644 --- a/modules/zedoBidAdapter.md +++ b/modules/zedoBidAdapter.md @@ -2,7 +2,7 @@ Module Name: ZEDO Bidder Adapter Module Type: Bidder Adapter -Maintainer: +Maintainer: prebidsupport@zedo.com # Description @@ -18,7 +18,7 @@ Module that connects to ZEDO's demand sources. { bidder: 'zedo', params: { - code: 2264002816 + code: 2264004118 } } ] From cd09dbcaf687fc0f7314ad70a63ec26cffddbe5d Mon Sep 17 00:00:00 2001 From: Sanoska Date: Mon, 16 Jul 2018 17:45:14 -0400 Subject: [PATCH 03/11] changes ti support the renderers --- modules/zedoBidAdapter.js | 26 ++++++++++++++++-------- test/spec/modules/zedoBidAdapter_spec.js | 8 ++++---- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 966cc03b45f..38fca275de2 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from 'src/utils'; import { registerBidder } from 'src/adapters/bidderFactory'; -import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes'; +import { BANNER, VIDEO } from 'src/mediaTypes'; import find from 'core-js/library/fn/array/find'; const BIDDER_CODE = 'zedo'; @@ -48,14 +48,15 @@ export const spec = { channel: channel, width: dims[0][0] ? dims[0][0] : 468, height: dims[0][1] ? dims[0][1] : 60, - dimension: dims[0][2] ? dims[0][2] : 9, // TODO : check default + dimension: dims[0][2] ? dims[0][2] : 0, // default to 0 version: '$prebid.version$', + keyword: '', transactionId: bidRequest.transactionId } const videoMediaType = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`); if (bidRequest.mediaType === VIDEO || videoMediaType) { placement['renderers'] = [{ - 'name': 'Inarticle' + 'name': 'Pre/Mid/Post roll' }] } else { placement['renderers'] = [{ @@ -123,9 +124,10 @@ function getCreative(ad) { * @return Bid */ function newBid(serverBid, creativeBid, bidderRequest) { + let prShr = (parseInt(creativeBid.cpm) * 0.7) / 1000000; const bid = { requestId: serverBid.slotId, - cpm: creativeBid.cpm, + cpm: prShr, creativeId: creativeBid.adId, dealId: 99999999, currency: 'USD', @@ -133,7 +135,7 @@ function newBid(serverBid, creativeBid, bidderRequest) { ttl: 300 }; - if (creativeBid.creativeDetails.type === 'Vast') { + if (creativeBid.creativeDetails.type === 'VAST') { Object.assign(bid, { width: creativeBid.width, height: creativeBid.height, @@ -162,6 +164,8 @@ function getSizes(requestSizes) { let dim = SIZE[sizeObj.width + 'x' + sizeObj.height]; if (dim) { dims.push([sizeObj.width, sizeObj.height, dim]); + } else { + dims.push([sizeObj.width, sizeObj.height, 0]); } } else if (typeof requestSizes === 'object') { for (let i = 0; i < requestSizes.length; i++) { @@ -170,15 +174,19 @@ function getSizes(requestSizes) { sizeObj.width = parseInt(size[0], 10); sizeObj.height = parseInt(size[1], 10); let dim = SIZE[sizeObj.width + 'x' + sizeObj.height]; - dims.push([sizeObj.width, sizeObj.height, dim]); + if (dim) { + dims.push([sizeObj.width, sizeObj.height, dim]); + } else { + dims.push([sizeObj.width, sizeObj.height, 0]); + } } } return dims; } -function parseMediaType(rtbBid) { - const adType = rtbBid.ad_type; - if (adType === VIDEO) { +function parseMediaType(creativeBid) { + const adType = creativeBid.creativeDetails.type; + if (adType === 'VAST') { return VIDEO; } else { return BANNER; diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 05a75ab5d0e..8656eee39b6 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -44,7 +44,7 @@ describe('The ZEDO bidding adapter', () => { expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; - expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":250,"dimension":9,"version":"$prebid.version$","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":250,"dimension":9,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); }); it('should properly build a channelCode request for video', () => { @@ -68,7 +68,7 @@ describe('The ZEDO bidding adapter', () => { expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; - expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Pre/Mid/Post roll"}]}]}'); }); }); describe('interpretResponse', () => { @@ -139,7 +139,7 @@ describe('The ZEDO bidding adapter', () => { 'type': 'StdBanner', 'adContent': '' }, - 'cpm': '1.2' + 'cpm': '1200000' } ] } @@ -159,7 +159,7 @@ describe('The ZEDO bidding adapter', () => { const bids = spec.interpretResponse(response, request); expect(bids).to.have.lengthOf(1); expect(bids[0].requestId).to.equal('ad1d762'); - expect(bids[0].cpm).to.equal('1.2'); + expect(bids[0].cpm).to.equal(0.84); expect(bids[0].width).to.equal('160'); expect(bids[0].height).to.equal('600'); }); From f134156bff05219f1fbf7c8579314017f11362e5 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Tue, 17 Jul 2018 16:48:23 -0400 Subject: [PATCH 04/11] changes to pass dimId --- modules/zedoBidAdapter.js | 68 +++++++++++------------- modules/zedoBidAdapter.md | 3 ++ test/spec/modules/zedoBidAdapter_spec.js | 7 ++- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 38fca275de2..6a33749e1ef 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -6,10 +6,10 @@ import find from 'core-js/library/fn/array/find'; const BIDDER_CODE = 'zedo'; const URL = '//z2.zedo.com/asw/fmb.json'; const SECURE_URL = '//z2.zedo.com/asw/fmb.json'; -const SIZE = { - '300x250': 9, - '160x600': 88, - '640x480': 85 // TODO check for 1x1 +const RENDERER_TYPE = { + '9': 'display', + '88': 'display', + '85': 'Pre/Mid/Post roll', }; export const spec = { @@ -24,7 +24,7 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.channelCode); + return !!(bid.params && bid.params.channelCode && bid.params.dimId); }, /** @@ -41,24 +41,24 @@ export const spec = { let channelCode = parseInt(bidRequest.params.channelCode); let network = parseInt(channelCode / 1000000); let channel = channelCode % 1000000; - let dims = getSizes(bidRequest.sizes); + let dim = getSizes(bidRequest.sizes); let placement = { id: bidRequest.bidId, network: network, channel: channel, - width: dims[0][0] ? dims[0][0] : 468, - height: dims[0][1] ? dims[0][1] : 60, - dimension: dims[0][2] ? dims[0][2] : 0, // default to 0 + width: dim[0], + height: dim[1], + dimension: bidRequest.params.dimId, version: '$prebid.version$', keyword: '', transactionId: bidRequest.transactionId } - const videoMediaType = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`); - if (bidRequest.mediaType === VIDEO || videoMediaType) { + let renderName = RENDERER_TYPE[String(bidRequest.params.dimId)] + if (renderName) { placement['renderers'] = [{ - 'name': 'Pre/Mid/Post roll' + 'name': renderName }] - } else { + } else { // default to display placement['renderers'] = [{ 'name': 'display' }] @@ -106,8 +106,10 @@ export const spec = { getUserSyncs: function (syncOptions) { if (syncOptions.iframeEnabled) { + let url = utils.getTopWindowLocation().protocol === 'http:' ? 'http://d3.zedo.com/rs/us/fcs.html' : 'https://tt3.zedo.com/rs/us/fcs.html'; return [{ - // TODO implement user sync + type: 'iframe', + url: url }]; } } @@ -143,10 +145,17 @@ function newBid(serverBid, creativeBid, bidderRequest) { ttl: 3600 }); } else { + let tracker = ''; + if (creativeBid.trackingData && creativeBid.trackingData.impressionTrackers) { + let trackerArr = creativeBid.trackingData.impressionTrackers; + for (let i in trackerArr) { + tracker = tracker + ''; + } + } Object.assign(bid, { width: creativeBid.width, height: creativeBid.height, - ad: creativeBid.creativeDetails.adContent + ad: creativeBid.creativeDetails.adContent + tracker }); } @@ -154,34 +163,21 @@ function newBid(serverBid, creativeBid, bidderRequest) { } /* Turn bid request sizes into ut-compatible format */ function getSizes(requestSizes) { - let dims = []; - let sizeObj = {}; - + let width = 0; + let height = 0; if (utils.isArray(requestSizes) && requestSizes.length === 2 && !utils.isArray(requestSizes[0])) { - sizeObj.width = parseInt(requestSizes[0], 10); - sizeObj.height = parseInt(requestSizes[1], 10); - let dim = SIZE[sizeObj.width + 'x' + sizeObj.height]; - if (dim) { - dims.push([sizeObj.width, sizeObj.height, dim]); - } else { - dims.push([sizeObj.width, sizeObj.height, 0]); - } + width = parseInt(requestSizes[0], 10); + height = parseInt(requestSizes[1], 10); } else if (typeof requestSizes === 'object') { for (let i = 0; i < requestSizes.length; i++) { let size = requestSizes[i]; - sizeObj = {}; - sizeObj.width = parseInt(size[0], 10); - sizeObj.height = parseInt(size[1], 10); - let dim = SIZE[sizeObj.width + 'x' + sizeObj.height]; - if (dim) { - dims.push([sizeObj.width, sizeObj.height, dim]); - } else { - dims.push([sizeObj.width, sizeObj.height, 0]); - } + width = parseInt(size[0], 10); + height = parseInt(size[1], 10); + break; } } - return dims; + return [width, height]; } function parseMediaType(creativeBid) { diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md index 259c4c02dee..9ffcd61f164 100644 --- a/modules/zedoBidAdapter.md +++ b/modules/zedoBidAdapter.md @@ -8,6 +8,8 @@ Maintainer: prebidsupport@zedo.com Module that connects to ZEDO's demand sources. +For video integration, ZEDO returns content as vastXML and requires the publisher to define the cache url in config passed to Prebid for it to be valid in the auction + # Test Parameters ``` var adUnits = [ @@ -19,6 +21,7 @@ Module that connects to ZEDO's demand sources. bidder: 'zedo', params: { code: 2264004118 + dimId: 9 } } ] diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 8656eee39b6..7531ae2fe5e 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -16,6 +16,7 @@ describe('The ZEDO bidding adapter', () => { bidder: 'zedo', params: { channelCode: 20000000, + dimId: 9 }, }; const isValid = spec.isBidRequestValid(bid); @@ -37,6 +38,7 @@ describe('The ZEDO bidding adapter', () => { sizes: [[300, 250]], params: { channelCode: 20000000, + dimId: 9 }, }, ]; @@ -61,6 +63,7 @@ describe('The ZEDO bidding adapter', () => { }, params: { channelCode: 20000000, + dimId: 85 }, }, ]; @@ -115,6 +118,7 @@ describe('The ZEDO bidding adapter', () => { bidId: 'test-bidId', params: { channelCode: 2000000, + dimId: 9 } }] }; @@ -152,7 +156,8 @@ describe('The ZEDO bidding adapter', () => { adUnitCode: 'test-requestId', bidId: 'test-bidId', params: { - zoneId: 123, + channelCode: 2000000, + dimId: 9 }, }] }; From c5293b7d6ad717935610a9c37258219f9d59508c Mon Sep 17 00:00:00 2001 From: Sanoska Date: Thu, 19 Jul 2018 16:30:31 -0400 Subject: [PATCH 05/11] fixed names of internal mapping --- integrationExamples/gpt/pbjs_example_gpt.html | 1 + modules/zedoBidAdapter.js | 29 ++++---- test/spec/modules/zedoBidAdapter_spec.js | 70 +++++++++++++++++-- 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/integrationExamples/gpt/pbjs_example_gpt.html b/integrationExamples/gpt/pbjs_example_gpt.html index 0cc7aca7cc4..b3c776e101c 100644 --- a/integrationExamples/gpt/pbjs_example_gpt.html +++ b/integrationExamples/gpt/pbjs_example_gpt.html @@ -293,6 +293,7 @@ bidder: 'zedo', params: { channelCode: 2264002816, //REQUIRED + dimId: 9 } } ] diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 6a33749e1ef..d97c1fc1de2 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -6,10 +6,16 @@ import find from 'core-js/library/fn/array/find'; const BIDDER_CODE = 'zedo'; const URL = '//z2.zedo.com/asw/fmb.json'; const SECURE_URL = '//z2.zedo.com/asw/fmb.json'; -const RENDERER_TYPE = { +const DIM_TYPE = { + '7': 'display', '9': 'display', - '88': 'display', - '85': 'Pre/Mid/Post roll', + '14': 'display', + '70': 'SBR', + '83': 'CurtainRaiser', + '85': 'Inarticle', + '86': 'pswipeup', + '88': 'Inview', + // '85': 'pre-mid-post-roll', }; export const spec = { @@ -53,10 +59,10 @@ export const spec = { keyword: '', transactionId: bidRequest.transactionId } - let renderName = RENDERER_TYPE[String(bidRequest.params.dimId)] - if (renderName) { + let dimType = DIM_TYPE[String(bidRequest.params.dimId)] + if (dimType) { placement['renderers'] = [{ - 'name': renderName + 'name': dimType }] } else { // default to display placement['renderers'] = [{ @@ -145,23 +151,16 @@ function newBid(serverBid, creativeBid, bidderRequest) { ttl: 3600 }); } else { - let tracker = ''; - if (creativeBid.trackingData && creativeBid.trackingData.impressionTrackers) { - let trackerArr = creativeBid.trackingData.impressionTrackers; - for (let i in trackerArr) { - tracker = tracker + ''; - } - } Object.assign(bid, { width: creativeBid.width, height: creativeBid.height, - ad: creativeBid.creativeDetails.adContent + tracker + ad: creativeBid.creativeDetails.adContent }); } return bid; } -/* Turn bid request sizes into ut-compatible format */ +/* Turn bid request sizes into compatible format */ function getSizes(requestSizes) { let width = 0; let height = 0; diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 7531ae2fe5e..3834e672bfe 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -29,16 +29,16 @@ describe('The ZEDO bidding adapter', () => { timeout: 3000, }; - it('should properly build a channelCode request for banner', () => { + it('should properly build a channelCode request for dim Id with type not defined', () => { const bidRequests = [ { bidder: 'zedo', adUnitCode: 'p12345', transactionId: '12345667', - sizes: [[300, 250]], + sizes: [[300, 200]], params: { channelCode: 20000000, - dimId: 9 + dimId: 10 }, }, ]; @@ -46,10 +46,10 @@ describe('The ZEDO bidding adapter', () => { expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; - expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":250,"dimension":9,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); }); - it('should properly build a channelCode request for video', () => { + it('should properly build a channelCode request for video with type defined', () => { const bidRequests = [ { bidder: 'zedo', @@ -71,7 +71,7 @@ describe('The ZEDO bidding adapter', () => { expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; - expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Pre/Mid/Post roll"}]}]}'); + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); }); }); describe('interpretResponse', () => { @@ -126,7 +126,7 @@ describe('The ZEDO bidding adapter', () => { expect(bids).to.have.lengthOf(0); }); - it('should properly parse a bid response with valid creative', () => { + it('should properly parse a bid response with valid display creative', () => { const response = { body: { ad: [ @@ -168,5 +168,61 @@ describe('The ZEDO bidding adapter', () => { expect(bids[0].width).to.equal('160'); expect(bids[0].height).to.equal('600'); }); + + it('should properly parse a bid response with valid video creative', () => { + const response = { + body: { + ad: [ + { + 'slotId': 'ad1d762', + 'network': '2000', + 'creatives': [ + { + 'adId': '12345', + 'height': '480', + 'width': '640', + 'isFoc': true, + 'creativeDetails': { + 'type': 'VAST', + 'adContent': '' + }, + 'cpm': '1200000' + } + ] + } + ] + } + }; + const request = { + bidRequests: [{ + bidder: 'zedo', + adUnitCode: 'test-requestId', + bidId: 'test-bidId', + params: { + channelCode: 2000000, + dimId: 85 + }, + }] + }; + const bids = spec.interpretResponse(response, request); + expect(bids).to.have.lengthOf(1); + expect(bids[0].requestId).to.equal('ad1d762'); + expect(bids[0].cpm).to.equal(0.84); + expect(bids[0].width).to.equal('640'); + expect(bids[0].height).to.equal('480'); + expect(bids[0].vastXml).to.not.equal(''); + expect(bids[0].ad).to.be.an('undefined'); + }); + }); + + describe('user sync', () => { + it('should register the iframe sync url', () => { + let syncs = spec.getUserSyncs({ + iframeEnabled: true + }); + expect(syncs).to.not.be.an('undefined'); + expect(syncs).to.have.lengthOf(1); + expect(syncs[0].type).to.equal('iframe'); + }); }); }); From bf996ec4cc126a3b4936e62c2657ab6950352a97 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Fri, 20 Jul 2018 10:56:18 -0400 Subject: [PATCH 06/11] added comment --- integrationExamples/gpt/pbjs_example_gpt.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integrationExamples/gpt/pbjs_example_gpt.html b/integrationExamples/gpt/pbjs_example_gpt.html index b3c776e101c..fbf21f1f856 100644 --- a/integrationExamples/gpt/pbjs_example_gpt.html +++ b/integrationExamples/gpt/pbjs_example_gpt.html @@ -293,7 +293,7 @@ bidder: 'zedo', params: { channelCode: 2264002816, //REQUIRED - dimId: 9 + dimId: 9 //REQUIRED } } ] From c768fe50142215cc604609d3cb5cf8a8e015f048 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Mon, 23 Jul 2018 16:03:29 -0400 Subject: [PATCH 07/11] added gdpr param to request and other fixes --- modules/zedoBidAdapter.js | 22 +++++++++--- test/spec/modules/zedoBidAdapter_spec.js | 44 ++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index d97c1fc1de2..0420c479ae9 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -39,7 +39,7 @@ export const spec = { * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. * @return ServerRequest Info describing the request to the server. */ - buildRequests: function (bidRequests) { + buildRequests: function (bidRequests, bidderRequest) { let data = { placements: [] }; @@ -59,6 +59,12 @@ export const spec = { keyword: '', transactionId: bidRequest.transactionId } + if (bidderRequest && bidderRequest.gdprConsent) { + if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { + data.gdpr = Number(bidderRequest.gdprConsent.gdprApplies); + } + data.gdpr_consent = bidderRequest.gdprConsent.consentString; + } let dimType = DIM_TYPE[String(bidRequest.params.dimId)] if (dimType) { placement['renderers'] = [{ @@ -110,9 +116,17 @@ export const spec = { return bids; }, - getUserSyncs: function (syncOptions) { + getUserSyncs: function (syncOptions, responses, gdprConsent) { if (syncOptions.iframeEnabled) { let url = utils.getTopWindowLocation().protocol === 'http:' ? 'http://d3.zedo.com/rs/us/fcs.html' : 'https://tt3.zedo.com/rs/us/fcs.html'; + if (gdprConsent && typeof gdprConsent.consentString === 'string') { + // add 'gdpr' only if 'gdprApplies' is defined + if (typeof gdprConsent.gdprApplies === 'boolean') { + url += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; + } else { + url += `?gdpr_consent=${gdprConsent.consentString}`; + } + } return [{ type: 'iframe', url: url @@ -132,10 +146,8 @@ function getCreative(ad) { * @return Bid */ function newBid(serverBid, creativeBid, bidderRequest) { - let prShr = (parseInt(creativeBid.cpm) * 0.7) / 1000000; const bid = { requestId: serverBid.slotId, - cpm: prShr, creativeId: creativeBid.adId, dealId: 99999999, currency: 'USD', @@ -148,12 +160,14 @@ function newBid(serverBid, creativeBid, bidderRequest) { width: creativeBid.width, height: creativeBid.height, vastXml: creativeBid.creativeDetails.adContent, + cpm: (parseInt(creativeBid.cpm) * 0.65) / 1000000, ttl: 3600 }); } else { Object.assign(bid, { width: creativeBid.width, height: creativeBid.height, + cpm: (parseInt(creativeBid.cpm) * 0.6) / 1000000, ad: creativeBid.creativeDetails.adContent }); } diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 3834e672bfe..6d0ab7c68f6 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -73,6 +73,36 @@ describe('The ZEDO bidding adapter', () => { const zedoRequest = request.data; expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); }); + + describe('buildGDPRRequests', () => { + let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; + const bidderRequest = { + timeout: 3000, + gdprConsent: { + 'consentString': consentString, + 'gdprApplies': true + } + }; + + it('should properly build request with gdpr consent', () => { + const bidRequests = [ + { + bidder: 'zedo', + adUnitCode: 'p12345', + transactionId: '12345667', + sizes: [[300, 200]], + params: { + channelCode: 20000000, + dimId: 10 + }, + }, + ]; + const request = spec.buildRequests(bidRequests, bidderRequest); + expect(request.method).to.equal('GET'); + const zedoRequest = request.data; + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}],"gdpr":1,"gdpr_consent":"BOJ8RZsOJ8RZsABAB8AAAAAZ+A=="}'); + }); + }); }); describe('interpretResponse', () => { it('should return an empty array when there is bid response', () => { @@ -164,7 +194,7 @@ describe('The ZEDO bidding adapter', () => { const bids = spec.interpretResponse(response, request); expect(bids).to.have.lengthOf(1); expect(bids[0].requestId).to.equal('ad1d762'); - expect(bids[0].cpm).to.equal(0.84); + expect(bids[0].cpm).to.equal(0.72); expect(bids[0].width).to.equal('160'); expect(bids[0].height).to.equal('600'); }); @@ -207,7 +237,7 @@ describe('The ZEDO bidding adapter', () => { const bids = spec.interpretResponse(response, request); expect(bids).to.have.lengthOf(1); expect(bids[0].requestId).to.equal('ad1d762'); - expect(bids[0].cpm).to.equal(0.84); + expect(bids[0].cpm).to.equal(0.78); expect(bids[0].width).to.equal('640'); expect(bids[0].height).to.equal('480'); expect(bids[0].vastXml).to.not.equal(''); @@ -224,5 +254,15 @@ describe('The ZEDO bidding adapter', () => { expect(syncs).to.have.lengthOf(1); expect(syncs[0].type).to.equal('iframe'); }); + + it('should pass gdpr params', () => { + let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { + gdprApplies: false, consentString: 'test' + }); + expect(syncs).to.not.be.an('undefined'); + expect(syncs).to.have.lengthOf(1); + expect(syncs[0].type).to.equal('iframe'); + expect(syncs[0].url).to.contains('gdpr=0'); + }); }); }); From 0aeb5e7cc702a7d8726a7c4c056f7791fb70c131 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Wed, 29 Aug 2018 11:42:43 -0400 Subject: [PATCH 08/11] modified api url --- modules/zedoBidAdapter.js | 8 ++++++-- modules/zedoBidAdapter.md | 2 +- test/spec/modules/zedoBidAdapter_spec.js | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 0420c479ae9..d6f75da4ece 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -4,8 +4,8 @@ import { BANNER, VIDEO } from 'src/mediaTypes'; import find from 'core-js/library/fn/array/find'; const BIDDER_CODE = 'zedo'; -const URL = '//z2.zedo.com/asw/fmb.json'; -const SECURE_URL = '//z2.zedo.com/asw/fmb.json'; +const URL = '//z2.zedo.com/asw/fmh.json'; +const SECURE_URL = '//z2.zedo.com/asw/fmh.json'; const DIM_TYPE = { '7': 'display', '9': 'display', @@ -15,6 +15,10 @@ const DIM_TYPE = { '85': 'Inarticle', '86': 'pswipeup', '88': 'Inview', + '100': 'display', + '101': 'display', + '102': 'display', + '103': 'display' // '85': 'pre-mid-post-roll', }; diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md index 9ffcd61f164..6555a1e6506 100644 --- a/modules/zedoBidAdapter.md +++ b/modules/zedoBidAdapter.md @@ -20,7 +20,7 @@ For video integration, ZEDO returns content as vastXML and requires the publishe { bidder: 'zedo', params: { - code: 2264004118 + channelCode: 2264004118 dimId: 9 } } diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 6d0ab7c68f6..d199156cfe4 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -43,7 +43,7 @@ describe('The ZEDO bidding adapter', () => { }, ]; const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); + expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmh.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); @@ -68,7 +68,7 @@ describe('The ZEDO bidding adapter', () => { }, ]; const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmb.json/); + expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmh.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); From 7f846dddea182c16c1ed383f54110463994eb929 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Thu, 6 Sep 2018 16:15:50 -0400 Subject: [PATCH 09/11] fix --- integrationExamples/gpt/hello_world.html | 193 +++++++++++++---------- modules/zedoBidAdapter.js | 48 ++++++ 2 files changed, 155 insertions(+), 86 deletions(-) diff --git a/integrationExamples/gpt/hello_world.html b/integrationExamples/gpt/hello_world.html index e1cdaa0dc29..d868b3d6628 100644 --- a/integrationExamples/gpt/hello_world.html +++ b/integrationExamples/gpt/hello_world.html @@ -8,94 +8,115 @@ --> - - - - - + + + - - - - - - - + } + + setTimeout(function () { + sendAdserverRequest(); + }, PREBID_TIMEOUT); + + + + + + +

Prebid.js Test

Div-1
- + +
+
- - \ No newline at end of file + + + + diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index d6f75da4ece..f5160668936 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -2,6 +2,7 @@ import * as utils from 'src/utils'; import { registerBidder } from 'src/adapters/bidderFactory'; import { BANNER, VIDEO } from 'src/mediaTypes'; import find from 'core-js/library/fn/array/find'; +import { Renderer } from 'src/Renderer'; const BIDDER_CODE = 'zedo'; const URL = '//z2.zedo.com/asw/fmh.json'; @@ -167,6 +168,15 @@ function newBid(serverBid, creativeBid, bidderRequest) { cpm: (parseInt(creativeBid.cpm) * 0.65) / 1000000, ttl: 3600 }); + const rendererOptions = utils.deepAccess( + bidderRequest, + 'renderer.options' + ); + + Object.assign(bid, { + adResponse: serverBid, + renderer: getRenderer(bid.adUnitCode, serverBid.slotId, 'http://demos.zedo.com/demos/prebid/fmpbgt.min.js', rendererOptions) + }); } else { Object.assign(bid, { width: creativeBid.width, @@ -197,6 +207,44 @@ function getSizes(requestSizes) { return [width, height]; } +function getRenderer(adUnitCode, rendererId, rendererUrl, rendererOptions = {}) { + const renderer = Renderer.install({ + id: rendererId, + url: rendererUrl, + config: rendererOptions, + loaded: false, + }); + + try { + renderer.setRender(videoRenderer); + } catch (err) { + utils.logWarn('Prebid Error calling setRender on renderer', err); + } + + renderer.setEventHandlers({ + impression: () => utils.logMessage('ZEDO video impression'), + loaded: () => utils.logMessage('ZEDO video loaded'), + ended: () => { + utils.logMessage('ZEDO renderer video ended'); + document.querySelector(`#${adUnitCode}`).style.display = 'none'; + } + }); + return renderer; +} + +function videoRenderer(bid) { + // push to render queue + bid.renderer.push(() => { + var rndr = new ZdPBTag(bid.adUnitCode, '3456', '640', '480', bid.vastXml); + rndr.renderAd(); + handleOutstreamRendererEvents.bind(null, bid) + }); +} + +function handleOutstreamRendererEvents(bid, id, eventName) { + bid.renderer.handleVideoEvent({ id, eventName }); +} + function parseMediaType(creativeBid) { const adType = creativeBid.creativeDetails.type; if (adType === 'VAST') { From e75970aa38c52e6c66bd7f74c69c86503e13f368 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Wed, 19 Sep 2018 12:43:45 -0400 Subject: [PATCH 10/11] fixed the secure api call --- integrationExamples/gpt/hello_world.html | 193 ++++++++++------------- modules/zedoBidAdapter.js | 12 +- test/spec/modules/zedoBidAdapter_spec.js | 8 +- 3 files changed, 99 insertions(+), 114 deletions(-) diff --git a/integrationExamples/gpt/hello_world.html b/integrationExamples/gpt/hello_world.html index d868b3d6628..e1cdaa0dc29 100644 --- a/integrationExamples/gpt/hello_world.html +++ b/integrationExamples/gpt/hello_world.html @@ -8,115 +8,94 @@ --> - - - - - - + + + - - - - - + + setTimeout(function() { + sendAdserverRequest(); + }, PREBID_TIMEOUT); + + + + + + + + +

Prebid.js Test

Div-1
- -
-
+
- - - - + + \ No newline at end of file diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index f5160668936..d493ff54e75 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -6,7 +6,7 @@ import { Renderer } from 'src/Renderer'; const BIDDER_CODE = 'zedo'; const URL = '//z2.zedo.com/asw/fmh.json'; -const SECURE_URL = '//z2.zedo.com/asw/fmh.json'; +const SECURE_URL = '//saxp.zedo.com/asw/fmh.json'; const DIM_TYPE = { '7': 'display', '9': 'display', @@ -154,6 +154,8 @@ function newBid(serverBid, creativeBid, bidderRequest) { const bid = { requestId: serverBid.slotId, creativeId: creativeBid.adId, + network: serverBid.network, + adType: creativeBid.creativeDetails.type, dealId: 99999999, currency: 'USD', netRevenue: true, @@ -172,17 +174,17 @@ function newBid(serverBid, creativeBid, bidderRequest) { bidderRequest, 'renderer.options' ); - + let rendererUrl = utils.getTopWindowLocation().protocol === 'http:' ? 'http://c14.zedo.com/gecko/beta/fmpbgt.min.js' : 'https://ss3.zedo.com/gecko/beta/fmpbgt.min.js'; Object.assign(bid, { adResponse: serverBid, - renderer: getRenderer(bid.adUnitCode, serverBid.slotId, 'http://demos.zedo.com/demos/prebid/fmpbgt.min.js', rendererOptions) + renderer: getRenderer(bid.adUnitCode, serverBid.slotId, rendererUrl, rendererOptions) }); } else { Object.assign(bid, { width: creativeBid.width, height: creativeBid.height, cpm: (parseInt(creativeBid.cpm) * 0.6) / 1000000, - ad: creativeBid.creativeDetails.adContent + ad: creativeBid.creativeDetails.adContent, }); } @@ -235,7 +237,7 @@ function getRenderer(adUnitCode, rendererId, rendererUrl, rendererOptions = {}) function videoRenderer(bid) { // push to render queue bid.renderer.push(() => { - var rndr = new ZdPBTag(bid.adUnitCode, '3456', '640', '480', bid.vastXml); + var rndr = new ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml); rndr.renderAd(); handleOutstreamRendererEvents.bind(null, bid) }); diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 85209edd4c3..abb0a5c97fb 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -43,7 +43,7 @@ describe('The ZEDO bidding adapter', function () { }, ]; const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmh.json/); + expect(request.url).to.match(/^\/\/saxp.zedo.com\/asw\/fmh.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); @@ -68,7 +68,7 @@ describe('The ZEDO bidding adapter', function () { }, ]; const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^\/\/z2.zedo.com\/asw\/fmh.json/); + expect(request.url).to.match(/^\/\/saxp.zedo.com\/asw\/fmh.json/); expect(request.method).to.equal('GET'); const zedoRequest = request.data; expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); @@ -234,14 +234,18 @@ describe('The ZEDO bidding adapter', function () { }, }] }; + const bids = spec.interpretResponse(response, request); expect(bids).to.have.lengthOf(1); expect(bids[0].requestId).to.equal('ad1d762'); expect(bids[0].cpm).to.equal(0.78); expect(bids[0].width).to.equal('640'); expect(bids[0].height).to.equal('480'); + expect(bids[0].adType).to.equal('VAST'); expect(bids[0].vastXml).to.not.equal(''); expect(bids[0].ad).to.be.an('undefined'); + expect(bids[0].renderer).not.to.be.an('undefined'); + bids[0].renderer.render(bids[0]); }); }); From c605a70d9b44399c46f2b308e5aa24a6c7498e34 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Wed, 19 Sep 2018 12:54:59 -0400 Subject: [PATCH 11/11] rolled back video event callback till we support it --- modules/zedoBidAdapter.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index d493ff54e75..970f28e47d5 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -239,14 +239,9 @@ function videoRenderer(bid) { bid.renderer.push(() => { var rndr = new ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml); rndr.renderAd(); - handleOutstreamRendererEvents.bind(null, bid) }); } -function handleOutstreamRendererEvents(bid, id, eventName) { - bid.renderer.handleVideoEvent({ id, eventName }); -} - function parseMediaType(creativeBid) { const adType = creativeBid.creativeDetails.type; if (adType === 'VAST') {