From 418baed6193f8309d4db627a67e24ec67c9ba525 Mon Sep 17 00:00:00 2001 From: Sanoska Date: Thu, 12 Jul 2018 16:09:23 -0400 Subject: [PATCH 01/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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/21] 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') { From 76aef1509cbd07b3e6f4aab5c744b0439eb389ff Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Wed, 17 Oct 2018 09:14:13 -0400 Subject: [PATCH 12/21] updated doc with video details --- modules/zedoBidAdapter.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md index 6555a1e6506..1ea35585a64 100644 --- a/modules/zedoBidAdapter.md +++ b/modules/zedoBidAdapter.md @@ -8,10 +8,16 @@ Maintainer: prebidsupport@zedo.com Module that connects to ZEDO's demand sources. +ZEDO supports both display and video. 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 +ZEDO has its own renderer and will render the video unit if not defined in the config. + + # Test Parameters +# display ``` + var adUnits = [ { code: 'banner-ad-div', @@ -28,3 +34,29 @@ For video integration, ZEDO returns content as vastXML and requires the publishe } ]; ``` +# video +``` + + var adUnit1 = [ + { + code: 'videoAdUnit', + mediaTypes: + { + video: + { + context: 'outstream', + playerSize: [640, 480] + } + }, + bids: [ + { + bidder: 'zedo', + params: + { + channelCode: 2264004593, + dimId: 85 + } + } + ] + }]; +``` \ No newline at end of file From c07b17ee856acc0a893231ffcfda7297ca44f349 Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Tue, 23 Oct 2018 18:04:22 -0400 Subject: [PATCH 13/21] added bid won and timeout pixel --- modules/zedoBidAdapter.js | 56 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 970f28e47d5..9ed2aff4f0c 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -3,6 +3,7 @@ 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'; +import * as url from 'src/url'; const BIDDER_CODE = 'zedo'; const URL = '//z2.zedo.com/asw/fmh.json'; @@ -22,6 +23,8 @@ const DIM_TYPE = { '103': 'display' // '85': 'pre-mid-post-roll', }; +const EVENT_PIXEL_URL = 'm1.zedo.com/log/p.gif'; +const SECURE_EVENT_PIXEL_URL = 'tt1.zedo.com/log/p.gif'; export const spec = { code: BIDDER_CODE, @@ -137,7 +140,23 @@ export const spec = { url: url }]; } - } + }, + + onTimeout: function (timeoutData) { + try { + logEvent('117', timeoutData); + } catch (e) { + utils.logError(e); + } + }, + + onBidWon: function (bid) { + try { + logEvent('116', [bid]); + } catch (e) { + utils.logError(e); + } + }, }; function getCreative(ad) { @@ -251,4 +270,39 @@ function parseMediaType(creativeBid) { } } +function logEvent(eid, data) { + let getParams = { + protocol: utils.getTopWindowLocation().protocol === 'http:' ? 'http' : 'https', + hostname: utils.getTopWindowLocation().protocol === 'http:' ? EVENT_PIXEL_URL : SECURE_EVENT_PIXEL_URL, + search: getLoggingData(eid, data) + }; + utils.triggerPixel(url.format(getParams)); +} + +function getLoggingData(eid, data) { + data = (utils.isArray(data) && data) || []; + + let params = {}; + let channel, network, dim, adunitCode, timeToRespond, cpm; + data.map((adunit) => { + adunitCode = adunit.adUnitCode; + channel = utils.deepAccess(adunit, 'params.0.channelCode') || 0; + network = channel > 0 ? parseInt(channel / 1000000) : 0; + dim = utils.deepAccess(adunit, 'params.0.dimId') * 256 || 0; + timeToRespond = adunit.timeToRespond; + cpm = adunit.cpm; + }); + params.n = network; + params.c = channel; + params.s = '0'; + params.x = dim; + params.ai = encodeURI('prebid^zedo^' + adunitCode + '^' + cpm + '^' + timeToRespond); + params.pu = utils.getTopWindowUrl() || ''; + params.eid = eid; + params.e = 'e'; + params.z = Math.random(); + + return params; +} + registerBidder(spec); From a6496ba259db82cb1314359dee05e03d3cfe4276 Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Wed, 24 Oct 2018 16:21:58 -0400 Subject: [PATCH 14/21] added testcase for bid events --- test/spec/modules/zedoBidAdapter_spec.js | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 93e65602984..2f280b8bd8d 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -268,4 +268,40 @@ describe('The ZEDO bidding adapter', function () { expect(syncs[0].url).to.contains('gdpr=0'); }); }); + + describe('bid events', function () { + it('should trigger a pixel', function () { + const bid = { + 'bidderCode': 'zedo', + 'width': '300', + 'height': '250', + 'statusMessage': 'Bid available', + 'adId': '148018fe5e', + 'cpm': 0.5, + 'ad': 'dummy data', + 'ad_id': '12345', + 'sizeId': '15', + 'params': [{ + 'channelCode': '123456', + 'dimId': '85' + }], + 'requestTimestamp': 1540401686, + 'responseTimestamp': 1540401687, + 'timeToRespond': 6253, + 'pbLg': '0.50', + 'pbMg': '0.50', + 'pbHg': '0.53', + 'adUnitCode': '/123456/header-bid-tag-0', + 'bidder': 'zedo', + 'size': '300x250', + 'adserverTargeting': { + 'hb_bidder': 'zedo', + 'hb_adid': '148018fe5e', + 'hb_pb': '10.00', + } + }; + spec.onBidWon(bid); + spec.onTimeout(bid); + }); + }); }); From d3e19dd8dccdefb37078591b01e21b1514578782 Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Thu, 25 Oct 2018 13:59:52 -0400 Subject: [PATCH 15/21] modified testcase --- modules/zedoBidAdapter.js | 2 +- test/spec/modules/zedoBidAdapter_spec.js | 48 +++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 9ed2aff4f0c..ebb9f1ca95e 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -289,7 +289,7 @@ function getLoggingData(eid, data) { channel = utils.deepAccess(adunit, 'params.0.channelCode') || 0; network = channel > 0 ? parseInt(channel / 1000000) : 0; dim = utils.deepAccess(adunit, 'params.0.dimId') * 256 || 0; - timeToRespond = adunit.timeToRespond; + timeToRespond = adunit.timeout ? adunit.timeout : adunit.timeToRespond; cpm = adunit.cpm; }); params.n = network; diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 2f280b8bd8d..8e6578d9b2c 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -270,7 +270,7 @@ describe('The ZEDO bidding adapter', function () { }); describe('bid events', function () { - it('should trigger a pixel', function () { + it('should trigger a win pixel', function () { const bid = { 'bidderCode': 'zedo', 'width': '300', @@ -281,6 +281,26 @@ describe('The ZEDO bidding adapter', function () { 'ad': 'dummy data', 'ad_id': '12345', 'sizeId': '15', + 'adResponse': + { + 'creatives': [ + { + 'adId': '12345', + 'height': '480', + 'width': '640', + 'isFoc': true, + 'creativeDetails': { + 'type': 'VAST', + 'adContent': '' + }, + 'seeder': { + 'network': 1234, + 'servedChan': 1234567, + }, + 'cpm': '1200000', + 'servedChan': 1234, + }] + }, 'params': [{ 'channelCode': '123456', 'dimId': '85' @@ -303,5 +323,31 @@ describe('The ZEDO bidding adapter', function () { spec.onBidWon(bid); spec.onTimeout(bid); }); + it('should trigger a timeout pixel', function () { + const bid = { + 'bidderCode': 'zedo', + 'width': '300', + 'height': '250', + 'statusMessage': 'Bid available', + 'adId': '148018fe5e', + 'cpm': 0.5, + 'ad': 'dummy data', + 'ad_id': '12345', + 'sizeId': '15', + 'params': [{ + 'channelCode': '123456', + 'dimId': '85' + }], + 'timeout': 1, + 'requestTimestamp': 1540401686, + 'responseTimestamp': 1540401687, + 'timeToRespond': 6253, + 'adUnitCode': '/123456/header-bid-tag-0', + 'bidder': 'zedo', + 'size': '300x250', + }; + spec.onBidWon(bid); + spec.onTimeout(bid); + }); }); }); From 4c8591510a1eb7737c4c2dbdd5ba3925acf2b65f Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Mon, 29 Oct 2018 14:30:31 -0400 Subject: [PATCH 16/21] fixed the url logged --- modules/zedoBidAdapter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index ebb9f1ca95e..c21b55b88a2 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -276,7 +276,7 @@ function logEvent(eid, data) { hostname: utils.getTopWindowLocation().protocol === 'http:' ? EVENT_PIXEL_URL : SECURE_EVENT_PIXEL_URL, search: getLoggingData(eid, data) }; - utils.triggerPixel(url.format(getParams)); + utils.triggerPixel(url.format(getParams).replace(/&/g, ';')); } function getLoggingData(eid, data) { @@ -296,8 +296,8 @@ function getLoggingData(eid, data) { params.c = channel; params.s = '0'; params.x = dim; - params.ai = encodeURI('prebid^zedo^' + adunitCode + '^' + cpm + '^' + timeToRespond); - params.pu = utils.getTopWindowUrl() || ''; + params.ai = encodeURI('Prebid^zedo^' + adunitCode + '^' + cpm + '^' + timeToRespond); + params.pu = encodeURI(utils.getTopWindowUrl()) || ''; params.eid = eid; params.e = 'e'; params.z = Math.random(); From 23b0cde0c090d3e698f55eb355bf7739c06abc05 Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Thu, 8 Nov 2018 11:14:52 -0500 Subject: [PATCH 17/21] tag param values passed ot renderer --- modules/zedoBidAdapter.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index c21b55b88a2..588fd81ac95 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -256,7 +256,12 @@ function getRenderer(adUnitCode, rendererId, rendererUrl, rendererOptions = {}) function videoRenderer(bid) { // push to render queue bid.renderer.push(() => { - var rndr = new ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml); + let channelCode = utils.deepAccess(bid, 'params.0.channelCode') || 0; + let dimId = utils.deepAccess(bid, 'params.0.dimId') || 0; + let options = utils.deepAccess(bid, 'params.0.options') || {}; + let channel = channelCode - (bid.network * 1000000); + var rndr = new ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml, channel, dimId, + (encodeURI(utils.getTopWindowUrl()) || ''), options); rndr.renderAd(); }); } From a427b5229b05c4d1b7a9c886b9a7bc03f93a0f22 Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Thu, 8 Nov 2018 12:56:15 -0500 Subject: [PATCH 18/21] added a conditioal check --- modules/zedoBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 588fd81ac95..f44493a7489 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -259,7 +259,7 @@ function videoRenderer(bid) { let channelCode = utils.deepAccess(bid, 'params.0.channelCode') || 0; let dimId = utils.deepAccess(bid, 'params.0.dimId') || 0; let options = utils.deepAccess(bid, 'params.0.options') || {}; - let channel = channelCode - (bid.network * 1000000); + let channel = (channelCode > 0) ? (channelCode - (bid.network * 1000000)) : 0; var rndr = new ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml, channel, dimId, (encodeURI(utils.getTopWindowUrl()) || ''), options); rndr.renderAd(); From 42762eda82d904be0a8207a0844cf723f2f2632e Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Mon, 14 Jan 2019 13:16:36 -0500 Subject: [PATCH 19/21] changes to support new param to adserver for purpose of tracking --- integrationExamples/gpt/pbjs_example_gpt.html | 3 ++- modules/zedoBidAdapter.js | 4 +++- modules/zedoBidAdapter.md | 10 ++++++---- test/spec/modules/zedoBidAdapter_spec.js | 9 +++++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/integrationExamples/gpt/pbjs_example_gpt.html b/integrationExamples/gpt/pbjs_example_gpt.html index 6852b9f680a..10973e3006f 100644 --- a/integrationExamples/gpt/pbjs_example_gpt.html +++ b/integrationExamples/gpt/pbjs_example_gpt.html @@ -300,7 +300,8 @@ bidder: 'zedo', params: { channelCode: 2264002816, //REQUIRED - dimId: 9 //REQUIRED + dimId: 9, //REQUIRED + pubId: 1 // OPTIONAL } }, { diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index f44493a7489..3a3e3f700c2 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -60,6 +60,7 @@ export const spec = { id: bidRequest.bidId, network: network, channel: channel, + publisher: bidRequest.params.pubId ? bidRequest.params.pubId : 0, width: dim[0], height: dim[1], dimension: bidRequest.params.dimId, @@ -294,12 +295,13 @@ function getLoggingData(eid, data) { channel = utils.deepAccess(adunit, 'params.0.channelCode') || 0; network = channel > 0 ? parseInt(channel / 1000000) : 0; dim = utils.deepAccess(adunit, 'params.0.dimId') * 256 || 0; + publisher = utils.deepAccess(adunit, 'params.0.pubId') || 0; timeToRespond = adunit.timeout ? adunit.timeout : adunit.timeToRespond; cpm = adunit.cpm; }); params.n = network; params.c = channel; - params.s = '0'; + params.s = publisher; params.x = dim; params.ai = encodeURI('Prebid^zedo^' + adunitCode + '^' + cpm + '^' + timeToRespond); params.pu = encodeURI(utils.getTopWindowUrl()) || ''; diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md index 1ea35585a64..e0f9101deaa 100644 --- a/modules/zedoBidAdapter.md +++ b/modules/zedoBidAdapter.md @@ -26,8 +26,9 @@ ZEDO has its own renderer and will render the video unit if not defined in the c { bidder: 'zedo', params: { - channelCode: 2264004118 - dimId: 9 + channelCode: 2264004118, // required + dimId: 9, // required + pubId: 1 // optional } } ] @@ -53,8 +54,9 @@ ZEDO has its own renderer and will render the video unit if not defined in the c bidder: 'zedo', params: { - channelCode: 2264004593, - dimId: 85 + channelCode: 2264004593, // required + dimId: 85, // required + pubId: 1 // optional } } ] diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js index 8e6578d9b2c..76301ba9018 100644 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ b/test/spec/modules/zedoBidAdapter_spec.js @@ -38,7 +38,8 @@ describe('The ZEDO bidding adapter', function () { sizes: [[300, 200]], params: { channelCode: 20000000, - dimId: 10 + dimId: 10, + pubId: 1 }, }, ]; @@ -46,7 +47,7 @@ describe('The ZEDO bidding adapter', function () { 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"}]}]}'); + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":1,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); }); it('should properly build a channelCode request for video with type defined', function () { @@ -71,7 +72,7 @@ describe('The ZEDO bidding adapter', function () { 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"}]}]}'); + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); }); describe('buildGDPRRequests', function () { @@ -100,7 +101,7 @@ describe('The ZEDO bidding adapter', function () { 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=="}'); + expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":0,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}],"gdpr":1,"gdpr_consent":"BOJ8RZsOJ8RZsABAB8AAAAAZ+A=="}'); }); }); }); From 2f3f95555dfa8b2c4dbcfd2434b59f2c8c6cadb7 Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Wed, 16 Jan 2019 15:40:21 -0500 Subject: [PATCH 20/21] passed param to renderer --- modules/zedoBidAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index 3a3e3f700c2..edccca9c035 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -259,11 +259,12 @@ function videoRenderer(bid) { bid.renderer.push(() => { let channelCode = utils.deepAccess(bid, 'params.0.channelCode') || 0; let dimId = utils.deepAccess(bid, 'params.0.dimId') || 0; + let publisher = utils.deepAccess(bid, 'params.0.pubId') || 0; let options = utils.deepAccess(bid, 'params.0.options') || {}; let channel = (channelCode > 0) ? (channelCode - (bid.network * 1000000)) : 0; var rndr = new ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml, channel, dimId, (encodeURI(utils.getTopWindowUrl()) || ''), options); - rndr.renderAd(); + rndr.renderAd(publisher); }); } From 99a0a166aff181dcdc6e9fc2efd607c1f6b14d36 Mon Sep 17 00:00:00 2001 From: Sanoska Gonsalves Date: Wed, 16 Jan 2019 16:15:57 -0500 Subject: [PATCH 21/21] missing variable defined --- modules/zedoBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js index edccca9c035..e95ba3da9e8 100644 --- a/modules/zedoBidAdapter.js +++ b/modules/zedoBidAdapter.js @@ -290,7 +290,7 @@ function getLoggingData(eid, data) { data = (utils.isArray(data) && data) || []; let params = {}; - let channel, network, dim, adunitCode, timeToRespond, cpm; + let channel, network, dim, publisher, adunitCode, timeToRespond, cpm; data.map((adunit) => { adunitCode = adunit.adUnitCode; channel = utils.deepAccess(adunit, 'params.0.channelCode') || 0;