From d18db957d709cc26af1fb0631b9b1818c856f1ec Mon Sep 17 00:00:00 2001 From: root Date: Mon, 5 Jun 2017 05:43:04 +0000 Subject: [PATCH 01/27] Add a new ucfunnel Adapter and test page --- adapters.json | 1 + .../gpt/pbjs_ucfunnel_gpt.html | 99 +++++++++++++++++++ src/adapters/ucfunnel.js | 96 ++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 integrationExamples/gpt/pbjs_ucfunnel_gpt.html create mode 100644 src/adapters/ucfunnel.js diff --git a/adapters.json b/adapters.json index b9ec1b70cd2..16fcb97ca2b 100644 --- a/adapters.json +++ b/adapters.json @@ -68,6 +68,7 @@ "trion", "prebidServer", "adsupply", + "ucfunnel", { "appnexus": { "alias": "brealtime" diff --git a/integrationExamples/gpt/pbjs_ucfunnel_gpt.html b/integrationExamples/gpt/pbjs_ucfunnel_gpt.html new file mode 100644 index 00000000000..9e233dc284c --- /dev/null +++ b/integrationExamples/gpt/pbjs_ucfunnel_gpt.html @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+ + +
+ +
+ + + diff --git a/src/adapters/ucfunnel.js b/src/adapters/ucfunnel.js new file mode 100644 index 00000000000..b40c0f74eea --- /dev/null +++ b/src/adapters/ucfunnel.js @@ -0,0 +1,96 @@ +import * as Adapter from './adapter.js'; +import bidfactory from 'src/bidfactory'; +import bidmanager from 'src/bidmanager'; +import * as utils from 'src/utils'; +import {ajax} from 'src/ajax'; +import {STATUS} from 'src/constants'; + +const VER ='ADGENT_PREBID-2017051801'; +const BIDDER_CODE = 'ucfunnel'; + +var ucfunnelAdapter = function ucfunnelAdapter() { + + function _callBids(params) { + var bids = params.bids || []; + + bids.forEach((bid) => { + try { + ajax(buildOptimizedCall(bid), bidCallback, undefined, { withCredentials: true }); + } catch (err) { + utils.logError('Error sending ucfunnel request for placement code ' + bid.placementCode, null, err); + } + + function bidCallback(responseText) { + try { + utils.logMessage('XHR callback function called for placement code: ' + bid.placementCode); + handleRpCB(responseText, bid); + } catch (err) { + if (typeof err === 'string') { + utils.logWarn(`${err} when processing ucfunnel response for placement code ${bid.placementCode}`); + } else { + utils.logError('Error processing ucfunnel response for placement code ' + bid.placementCode, null, err); + } + + // indicate that there is no bid for this placement + let badBid = bidfactory.createBid(STATUS.NO_BID, bid); + badBid.bidderCode = bid.bidder; + badBid.error = err; + bidmanager.addBidResponse(bid.placementCode, badBid); + } + } + }); + } + + function buildOptimizedCall(bid) { + bid.startTime = new Date().getTime(); + + var host = window.location.host, + page = window.location.pathname, + refer = document.referrer, + language = navigator.language, + dnt = (navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1") ? 1 : 0; + + var queryString = [ + 'ifr', 0, + 'bl', language, + 'je', 1, + 'dnt', dnt, + 'host', host, + 'u', page, + 'ru', refer, + 'adid', bid.params.adid, + 'w', bid.params.width, + 'h', bid.params.height, + 'ver', VER + ]; + + return queryString.reduce( + (memo, curr, index) => + index % 2 === 0 && queryString[index + 1] !== undefined + ? memo + curr + '=' + encodeURIComponent(queryString[index + 1]) + '&' + : memo, + '//agent.aralego.com/header?' + ).slice(0, -1); + } + + function handleRpCB(responseText, bidRequest) { + let ad = JSON.parse(responseText); // can throw + + var bid = bidfactory.createBid(STATUS.GOOD, bidRequest); + bid.creative_id = ad.ad_id; + bid.bidderCode = BIDDER_CODE; + bid.cpm = ad.cpm || 0; + bid.ad = ad.adm; + bid.width = ad.width; + bid.height = ad.height; + bid.dealId = ad.deal; + + bidmanager.addBidResponse(bidRequest.placementCode, bid); + } + + return { + callBids: _callBids + }; +}; + +module.exports = ucfunnelAdapter; From f82a4b7dd45af9c74ef783eb4f23b2131523fbfe Mon Sep 17 00:00:00 2001 From: root Date: Mon, 5 Jun 2017 05:43:04 +0000 Subject: [PATCH 02/27] Add a new ucfunnel Adapter and test page --- src/adapters/ucfunnel.js | 5 +- test/spec/adapters/ucfunnel_spec.js | 106 ++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 test/spec/adapters/ucfunnel_spec.js diff --git a/src/adapters/ucfunnel.js b/src/adapters/ucfunnel.js index b40c0f74eea..b99218ae2ca 100644 --- a/src/adapters/ucfunnel.js +++ b/src/adapters/ucfunnel.js @@ -5,11 +5,10 @@ import * as utils from 'src/utils'; import {ajax} from 'src/ajax'; import {STATUS} from 'src/constants'; -const VER ='ADGENT_PREBID-2017051801'; +const VER = 'ADGENT_PREBID-2017051801'; const BIDDER_CODE = 'ucfunnel'; var ucfunnelAdapter = function ucfunnelAdapter() { - function _callBids(params) { var bids = params.bids || []; @@ -48,7 +47,7 @@ var ucfunnelAdapter = function ucfunnelAdapter() { page = window.location.pathname, refer = document.referrer, language = navigator.language, - dnt = (navigator.doNotTrack == "yes" || navigator.doNotTrack == "1" || navigator.msDoNotTrack == "1") ? 1 : 0; + dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; var queryString = [ 'ifr', 0, diff --git a/test/spec/adapters/ucfunnel_spec.js b/test/spec/adapters/ucfunnel_spec.js new file mode 100644 index 00000000000..8c57227ce9f --- /dev/null +++ b/test/spec/adapters/ucfunnel_spec.js @@ -0,0 +1,106 @@ +import { expect } from 'chai'; +import Adapter from '../../../src/adapters/ucfunnel'; +import adapterManager from 'src/adaptermanager'; +import bidManager from 'src/bidmanager'; +import CONSTANTS from 'src/constants.json'; + +describe('ucfunnel adapter tests', function () { + let sandbox; + const adUnit = { // TODO CHANGE + code: 'ucfunnel', + sizes: [[300, 250]], + bids: [{ + bidder: 'ucfunnel', + params: { + adid: 'test-ad-83444226E44368D1E32E49EEBE6D29', + width: 300, + height: 250 + } + }] + }; + + const response = { + ad_id: 'ad-83444226E44368D1E32E49EEBE6D29', + adm: '
', + cpm: 0.01, + height: 250, + width: 300 + }; + + beforeEach(() => { + sandbox = sinon.sandbox.create(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + describe('ucfunnel callBids validation', () => { + let bids, + server; + + beforeEach(() => { + bids = []; + server = sinon.fakeServer.create(); + + sandbox.stub(bidManager, 'addBidResponse', (elemId, bid) => { + bids.push(bid); + }); + }); + + afterEach(() => { + server.restore(); + }); + + let adapter = adapterManager.bidderRegistry['ucfunnel']; + + it('Valid bid-request', () => { + sandbox.stub(adapter, 'callBids'); + adapterManager.callBids({ + adUnits: [clone(adUnit)] + }); + + let bidderRequest = adapter.callBids.getCall(0).args[0]; + + expect(bidderRequest).to.have.property('bids') + .that.is.an('array') + .with.lengthOf(1); + + expect(bidderRequest).to.have.deep.property('bids[0]') + .to.have.property('bidder', 'ucfunnel'); + + expect(bidderRequest).to.have.deep.property('bids[0]') + .with.property('sizes') + .that.is.an('array') + .with.lengthOf(1) + .that.deep.equals(adUnit.sizes); + expect(bidderRequest).to.have.deep.property('bids[0]') + .with.property('params') + .to.have.property('adid', 'test-ad-83444226E44368D1E32E49EEBE6D29'); + expect(bidderRequest).to.have.deep.property('bids[0]') + .with.property('params') + .to.have.property('width', 300); + }); + + it('Valid bid-response', () => { + server.respondWith(JSON.stringify( + response + )); + adapterManager.callBids({ + adUnits: [clone(adUnit)] + }); + server.respond(); + + expect(bids).to.be.lengthOf(1); + expect(bids[0].getStatusCode()).to.equal(CONSTANTS.STATUS.GOOD); + expect(bids[0].bidderCode).to.equal('ucfunnel'); + expect(bids[0].width).to.equal(300); + expect(bids[0].height).to.equal(250); + expect(bids[0].cpm).to.equal(0.01); + }); + }); +}); + +function clone(obj) { + return JSON.parse(JSON.stringify(obj)); +} From 4c917753b51c41e2e955a81acd0af5f9e92eef3a Mon Sep 17 00:00:00 2001 From: Ryan Chou Date: Fri, 16 Jun 2017 12:29:12 +0800 Subject: [PATCH 03/27] 1. Use prebid lib in the repo to keep updated 2. Replace var with let 3. Put JSON.parse(JSON.stringify()) into try catch block --- integrationExamples/gpt/pbjs_ucfunnel_gpt.html | 2 +- src/adapters/ucfunnel.js | 12 ++++++------ test/spec/adapters/ucfunnel_spec.js | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/integrationExamples/gpt/pbjs_ucfunnel_gpt.html b/integrationExamples/gpt/pbjs_ucfunnel_gpt.html index 9e233dc284c..67881d7168d 100644 --- a/integrationExamples/gpt/pbjs_ucfunnel_gpt.html +++ b/integrationExamples/gpt/pbjs_ucfunnel_gpt.html @@ -28,7 +28,7 @@ - + + - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; + + + + + + - - - - - - + pbjs.que.push(function() { + pbjs.setConfig({ + debug: true, + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + } + }); - + var allSlotsBidWon = function allSlotsBidWon() { + console.log('allSlotsBidWon called'); + }; + pbjs.onEvent('bidWon', allSlotsBidWon); + + var adUnits = [ + { + code: 'div-gpt-ad-1495530934718-0', + sizes: [[300, 250]], + bids: [{ + bidder: 'ucfunnel', + params: { + adid: "test-ad-34BBD2AA24B678BBFD4E7B9EE3B872D" + } + } + ] + }, + { + code: '/18087395/PrebidTest/PrebidNativeTest1', + sizes: [ + [1, 1] + ], + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + image: { + required: true + }, + sponsoredBy: { + required: true + }, + icon: { + required: false + }, + } + }, + bids: [{ + bidder: 'ucfunnel', + params: { + adid: 'test-ad-627736446B2BD3A60E8AEABDB7BD833E', + } + }] + } + ]; + + var videoAdUnit = { + code: 'video1', + mediaTypes: { + video: { + playerSize: [640, 360], + context: 'instream' + } + }, + bids: [{ + bidder: 'ucfunnel', + params: { + adid: 'test-ad-9A22D466494297EAC443D967B2622DA9', + } + }] + }; + + pbjs.addAdUnits(adUnits); + pbjs.requestBids({ + bidsBackHandler: function(bidResponses) { + initAdserver(); + } + }); + pbjs.addAdUnits(videoAdUnit); + pbjs.requestBids({ + bidsBackHandler: function(bids) { + var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ + adUnit: videoAdUnit, + params: { + iu: '/18087395/PrebidTest/PrebidVideoTest1', + output: 'vast' + } + }); + invokeVideoPlayer(videoUrl); + } + }); + + }); + + + // GPT setup + googletag.cmd.push(function() { + var slot2 = googletag.defineSlot('/18087395/PrebidTest/PrebidNativeTest1', 'fluid', 'div-2').addService(googletag.pubads()); + googletag.pubads().disableInitialLoad(); + googletag.pubads().enableSingleRequest(); + googletag.enableServices(); + }); + - -

Prebid.js Test

-
Div-1
- -
+ +

Prebid.js Banner

+ +
-
+
+ +

Prebid Native

+
+

No response

+ +
+ + +

Prebid Video -- video.js

+
+ +
+ + diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index c9548a280a0..b76b30f1de2 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -1,21 +1,38 @@ import * as utils from 'src/utils'; import {registerBidder} from 'src/adapters/bidderFactory'; -import { BANNER } from 'src/mediaTypes'; +import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes'; const VER = 'ADGENT_PREBID-2018011501'; -const BID_REQUEST_BASE_URL = '//hb.aralego.com/header'; -const UCFUNNEL_BIDDER_CODE = 'ucfunnel'; +const BIDDER_CODE = 'ucfunnel'; + +const VIDEO_CONTEXT = { + INSTREAM: 0, + OUSTREAM: 2 +} export const spec = { - code: UCFUNNEL_BIDDER_CODE, - supportedMediaTypes: [BANNER], + code: BIDDER_CODE, + ENDPOINT: '//hb.aralego.com/header', + supportedMediaTypes: [BANNER, VIDEO, NATIVE], /** * Check if the bid is a valid zone ID in either number or string form * @param {object} bid the ucfunnel bid to validate * @return boolean for whether or not a bid is valid */ isBidRequestValid: function(bid) { - return !!(bid && bid.params && bid.params.adid && typeof bid.params.adid === 'string'); + const isVideoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); + const videoContext = utils.deepAccess(bid, 'mediaTypes.video.context'); + + if (typeof bid.params !== 'object' || typeof bid.params.adid != 'string') { + return false; + } + + if (isVideoMediaType && videoContext === 'outstream') { + utils.logWarn('Warning: outstream video is not supported yet'); + return false; + } + + return true; }, /** @@ -23,21 +40,19 @@ export const spec = { * @param {*} bidderRequest * @return {ServerRequest} */ - buildRequests: function(validBidRequests, bidderRequest) { - var bidRequests = []; - for (var i = 0; i < validBidRequests.length; i++) { - var bid = validBidRequests[i]; - - var ucfunnelUrlParams = buildUrlParams(bid, bidderRequest); - - bidRequests.push({ - method: 'GET', - url: BID_REQUEST_BASE_URL, - bidRequest: bid, - data: ucfunnelUrlParams - }); - } - return bidRequests; + buildRequests: function(bids, bidderRequest) { + return bids.map(bid => { + return { + method: 'POST', + url: location.protocol + spec.ENDPOINT, + data: getRequestData(bid, bidderRequest), + options: { + contentType: 'application/json', + withCredentials: true + }, + bidRequest: bid + } + }); }, /** @@ -46,55 +61,150 @@ export const spec = { * @return {Bid[]} An array of formatted bids. */ interpretResponse: function (ucfunnelResponseObj, request) { - var bidResponses = []; - var bidRequest = request.bidRequest; - var responseBody = ucfunnelResponseObj ? ucfunnelResponseObj.body : {}; + const bidRequest = request.bidRequest; + const ad = ucfunnelResponseObj ? ucfunnelResponseObj.body : {}; + const videoPlayerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); - bidResponses.push({ + let bid = { requestId: bidRequest.bidId, - cpm: responseBody.cpm || 0, - width: responseBody.width, - height: responseBody.height, - creativeId: responseBody.ad_id, - dealId: responseBody.deal || null, + cpm: ad.cpm || 0, + creativeId: ad.ad_id, + dealId: ad.deal || null, currency: 'USD', netRevenue: true, - ttl: 1000, - mediaType: BANNER, - ad: responseBody.adm - }); + ttl: 1000 + }; + + if (ad.creative_type) { + bid.mediaType = ad.creative_type; + } + + switch (ad.creative_type) { + case NATIVE: + let nativeAd = ad.native; + Object.assign(bid, { + width: 1, + height: 1, + native: { + title: nativeAd.title, + body: nativeAd.desc, + cta: nativeAd.ctatext, + sponsoredBy: nativeAd.sponsored, + image: nativeAd.image || nativeAd.image.url, + icon: nativeAd.icon || nativeAd.icon.url, + clickUrl: nativeAd.clickUrl, + impressionTrackers: nativeAd.impressionTrackers, + } + }); + break; + case VIDEO: + Object.assign(bid, { + vastXml: ad.adm + }); + + if (videoPlayerSize && videoPlayerSize.length === 2) { + Object.assign(bid, { + width: videoPlayerSize[0], + height: videoPlayerSize[1] + }); + } + break; + case BANNER: + default: + Object.assign(bid, { + width: ad.width, + height: ad.height, + ad: ad.adm + }); + } - return bidResponses; + return [bid]; + }, + + getUserSyncs: function(syncOptions) { + if (syncOptions.iframeEnabled) { + return [{ + type: 'iframe', + url: '//cdn.aralego.com/ucfad/cookie/sync.html' + }]; + } else if (syncOptions.pixelEnabled) { + return [{ + type: 'image', + url: '//sync.aralego.com/idSync' + }]; + } } }; registerBidder(spec); -function buildUrlParams(bid, bidderRequest) { - const host = utils.getTopWindowLocation().host; - const page = utils.getTopWindowLocation().pathname; - const refer = document.referrer; +function transformSizes(requestSizes) { + if (utils.isArray(requestSizes) && requestSizes.length === 2 && !utils.isArray(requestSizes[0])) { + return [parseInt(requestSizes[0], 10), parseInt(requestSizes[1], 10)]; + } else if (typeof requestSizes === 'object' && requestSizes.length) { + return requestSizes[0]; + } +} + +function parseSizes(bid) { + let params = bid.params; + if (bid.mediaType === VIDEO) { + let size = []; + if (params.video && params.video.playerWidth && params.video.playerHeight) { + size = [ + params.video.playerWidth, + params.video.playerHeight + ]; + return size; + } + } + + return transformSizes(bid.sizes); +} + +function getRequestData(bid, bidderRequest) { + const size = parseSizes(bid); + const loc = utils.getTopWindowLocation(); + const host = loc.host; + const page = loc.href; + const ref = utils.getTopWindowReferrer(); const language = navigator.language; const dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; + const videoContext = utils.deepAccess(bid, 'mediaTypes.video.context'); + const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); - let queryString = [ - 'ifr', '0', - 'bl', language, - 'je', '1', - 'dnt', dnt, - 'host', host, - 'u', page, - 'ru', refer, - 'adid', utils.getBidIdParameter('adid', bid.params), - 'ver', VER - ]; + // general bid data + let bidData = { + ver: VER, + ifr: 0, + bl: language, + je: 1, + dnt: dnt, + host: host, + u: page, + ru: ref, + adid: utils.getBidIdParameter('adid', bid.params), + w: size[0], + h: size[1] + }; + + if (bid.mediaType === 'video' || videoMediaType) { + switch (videoContext) { + case 'outstream': + bidData.atype = VIDEO_CONTEXT.OUSTREAM; + break; + case 'instream': + default: + bidData.atype = VIDEO_CONTEXT.INSTREAM; + break; + } + } if (bidderRequest && bidderRequest.gdprConsent) { - queryString.push('gdpr', bidderRequest.gdprConsent.gdprApplies ? 1 : 0); - queryString.push('euconsent', bidderRequest.gdprConsent.consentString); + Object.assign(bidData, { + gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, + euconsent: bidderRequest.gdprConsent.consentString + }); } - return queryString.reduce( - (memo, curr, index) => - index % 2 === 0 && queryString[index + 1] !== undefined ? memo + curr + '=' + encodeURIComponent(queryString[index + 1]) + '&' : memo, '' - ).slice(0, -1); + return bidData; } diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 152c7c39b1e..b7a859faa36 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -23,16 +23,6 @@ const invalidBidReq = { auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' }; -const bidReq = [{ - bidder: BIDDER_CODE, - params: { - adid: 'test-ad-83444226E44368D1E32E49EEBE6D29' - }, - sizes: [[300, 250]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' -}]; - const validBidRes = { ad_id: 'ad-83444226E44368D1E32E49EEBE6D29', adm: '
', @@ -79,23 +69,45 @@ describe('ucfunnel Adapter', () => { }); }); describe('build request', () => { - it('Verify bid request', () => { - const request = spec.buildRequests(bidReq); - expect(request[0].method).to.equal('GET'); - expect(request[0].url).to.equal(URL); - expect(request[0].data).to.match(new RegExp(`${bidReq[0].params.adid}`)); + it('should create a POST request for every bid', () => { + const request = spec.buildRequests([validBidReq]); + expect(request[0].method).to.equal('POST'); + expect(request[0].url).to.equal(location.protocol + spec.ENDPOINT); + }); + + it('should attach the bid request object', () => { + const requests = spec.buildRequests([ validBidReq ]); + expect(requests[0].bidRequest).to.equal(validBidReq); + }); + + it('should attach request data', () => { + const requests = spec.buildRequests([ validBidReq ]); + const data = requests[0].data; + const [ width, height ] = validBidReq.sizes[0]; + expect(data.w).to.equal(width); + expect(data.h).to.equal(height); + }); + + it('must parse bid size from a nested array', () => { + const width = 640; + const height = 480; + validBidReq.sizes = [[ width, height ]]; + const requests = spec.buildRequests([ validBidReq ]); + const data = requests[0].data; + expect(data.w).to.equal(width); + expect(data.h).to.equal(height); }); }); describe('interpretResponse', () => { it('should build bid array', () => { - const request = spec.buildRequests(bidReq); + const request = spec.buildRequests([ validBidReq ]); const result = spec.interpretResponse({body: bidResponse}, request[0]); expect(result.length).to.equal(1); }); it('should have all relevant fields', () => { - const request = spec.buildRequests(bidReq); + const request = spec.buildRequests([ validBidReq ]); const result = spec.interpretResponse({body: bidResponse}, request[0]); const bid = result[0]; From 7d8dc52cb35877df01b1957ea3967338cc253a45 Mon Sep 17 00:00:00 2001 From: Ryan Chou Date: Wed, 20 Jun 2018 18:51:18 +0800 Subject: [PATCH 16/27] Remove demo page. Add more test cases. --- .../gpt/pbjs_ucfunnel_gpt.html | 244 ------------------ modules/ucfunnelBidAdapter.js | 2 +- test/spec/modules/ucfunnelBidAdapter_spec.js | 180 +++++++++---- 3 files changed, 128 insertions(+), 298 deletions(-) delete mode 100644 integrationExamples/gpt/pbjs_ucfunnel_gpt.html diff --git a/integrationExamples/gpt/pbjs_ucfunnel_gpt.html b/integrationExamples/gpt/pbjs_ucfunnel_gpt.html deleted file mode 100644 index faddab35ae3..00000000000 --- a/integrationExamples/gpt/pbjs_ucfunnel_gpt.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -

Prebid.js Banner

- -
- -
- -

Prebid Native

-
-

No response

- -
- - -

Prebid Video -- video.js

-
- -
- - - - diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index b76b30f1de2..44a834c6962 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -63,7 +63,7 @@ export const spec = { interpretResponse: function (ucfunnelResponseObj, request) { const bidRequest = request.bidRequest; const ad = ucfunnelResponseObj ? ucfunnelResponseObj.body : {}; - const videoPlayerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); + const videoPlayerSize = parseSizes(bidRequest); let bid = { requestId: bidRequest.bidId, diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index b7a859faa36..2b774bb7e5a 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -1,19 +1,20 @@ import { expect } from 'chai'; import { spec } from 'modules/ucfunnelBidAdapter'; +import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes'; const URL = '//hb.aralego.com/header'; const BIDDER_CODE = 'ucfunnel'; -const validBidReq = { +const validBannerBidReq = { bidder: BIDDER_CODE, params: { - adid: 'test-ad-83444226E44368D1E32E49EEBE6D29' + adid: 'ad-34BBD2AA24B678BBFD4E7B9EE3B872D' }, sizes: [[300, 250]], bidId: '263be71e91dd9d', auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', }; -const invalidBidReq = { +const invalidBannerBidReq = { bidder: BIDDER_CODE, params: { adid: 123456789 @@ -23,67 +24,100 @@ const invalidBidReq = { auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' }; -const validBidRes = { - ad_id: 'ad-83444226E44368D1E32E49EEBE6D29', +const validBannerBidRes = { + creative_type: BANNER, + ad_id: 'ad-34BBD2AA24B678BBFD4E7B9EE3B872D', adm: '
', cpm: 0.01, height: 250, width: 300 }; -const bidResponse = validBidRes; - -const bidResArray = [ - validBidRes, - { - ad: '', - bidRequestId: '263be71e91dd9d', - cpm: 100, - adId: '123abc', - currency: 'USD', - netRevenue: true, - width: 300, - height: 250, - ttl: 360 +const validVideoBidReq = { + bidder: BIDDER_CODE, + params: { + adid: 'ad-9A22D466494297EAC443D967B2622DA9' + }, + sizes: [[640, 360]], + bidId: '263be71e91dd9f', + auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', +}; + +const validVideoBidRes = { + creative_type: VIDEO, + ad_id: 'ad-9A22D466494297EAC443D967B2622DA9', + adm: 'ucX I-Primo 00:00:30', + cpm: 0.01, + width: 640, + height: 360 +}; + +const validNativeBidReq = { + bidder: BIDDER_CODE, + params: { + adid: 'ad-627736446B2BD3A60E8AEABDB7BD833E' }, - { - ad: '
Hello
', - bidRequestId: '', - cpm: 0, - adId: '123abc', - currency: 'USD', - netRevenue: true, - width: 300, - height: 250, - ttl: 360 - } -]; + sizes: [[1, 1]], + bidId: '263be71e91dda0', + auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', +}; + +const validNativeBidRes = { + creative_type: NATIVE, + ad_id: 'ad-9A22D466494297EAC443D967B2622DA9', + native: { + title: 'ucfunnel adExchange', + body: 'We monetize your traffic via historic data driven protocol', + cta: 'Learn more', + sponsoredBy: 'ucfunnel Co., Ltd.', + image: { + url: 'https://cdn.aralego.net/img/main/AdGent-1200x627.jpg', + width: 1200, + height: 627 + }, + icon: { + url: 'https://cdn.aralego.net/img/logo/logo-84x84.jpg', + widt: 84, + heigh: 84 + }, + clickUrl: 'https://www.ucfunnel.com', + impressionTrackers: ['https://www.aralego.net/imp?mf=native&adid=ad-9A22D466494297EAC443D967B2622DA9&auc=9ad1fa8d-2297-4660-a018-b39945054746'], + }, + cpm: 0.01, + height: 1, + width: 1 +}; describe('ucfunnel Adapter', () => { describe('request', () => { it('should validate bid request', () => { - expect(spec.isBidRequestValid(validBidReq)).to.equal(true); + expect(spec.isBidRequestValid(validBannerBidReq)).to.equal(true); }); it('should not validate incorrect bid request', () => { - expect(spec.isBidRequestValid(invalidBidReq)).to.equal(false); + expect(spec.isBidRequestValid(invalidBannerBidReq)).to.equal(false); }); }); describe('build request', () => { + const request = spec.buildRequests([validBannerBidReq]); it('should create a POST request for every bid', () => { - const request = spec.buildRequests([validBidReq]); expect(request[0].method).to.equal('POST'); expect(request[0].url).to.equal(location.protocol + spec.ENDPOINT); }); + it('should ensure contentType is `application/json`', () => { + expect(request[0].options).to.deep.equal({ + contentType: 'application/json', + withCredentials: true + }); + }); + it('should attach the bid request object', () => { - const requests = spec.buildRequests([ validBidReq ]); - expect(requests[0].bidRequest).to.equal(validBidReq); + expect(request[0].bidRequest).to.equal(validBannerBidReq); }); it('should attach request data', () => { - const requests = spec.buildRequests([ validBidReq ]); - const data = requests[0].data; - const [ width, height ] = validBidReq.sizes[0]; + const data = request[0].data; + const [ width, height ] = validBannerBidReq.sizes[0]; expect(data.w).to.equal(width); expect(data.h).to.equal(height); }); @@ -91,8 +125,8 @@ describe('ucfunnel Adapter', () => { it('must parse bid size from a nested array', () => { const width = 640; const height = 480; - validBidReq.sizes = [[ width, height ]]; - const requests = spec.buildRequests([ validBidReq ]); + validBannerBidReq.sizes = [[ width, height ]]; + const requests = spec.buildRequests([ validBannerBidReq ]); const data = requests[0].data; expect(data.w).to.equal(width); expect(data.h).to.equal(height); @@ -100,21 +134,61 @@ describe('ucfunnel Adapter', () => { }); describe('interpretResponse', () => { - it('should build bid array', () => { - const request = spec.buildRequests([ validBidReq ]); - const result = spec.interpretResponse({body: bidResponse}, request[0]); - expect(result.length).to.equal(1); + describe('should support banner', () => { + const request = spec.buildRequests([ validBannerBidReq ]); + const result = spec.interpretResponse({body: validBannerBidRes}, request[0]); + it('should build bid array for banner', () => { + expect(result.length).to.equal(1); + }); + + it('should have all relevant fields', () => { + const bid = result[0]; + + expect(bid.mediaType).to.equal(BANNER); + expect(bid.ad).to.exist; + expect(bid.requestId).to.equal('263be71e91dd9d'); + expect(bid.cpm).to.equal(0.01); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + }); + }); + + describe('should support video', () => { + const request = spec.buildRequests([ validVideoBidReq ]); + const result = spec.interpretResponse({body: validVideoBidRes}, request[0]); + it('should build bid array', () => { + expect(result.length).to.equal(1); + }); + + it('should have all relevant fields', () => { + const bid = result[0]; + + expect(bid.mediaType).to.equal(VIDEO); + expect(bid.vastXml).to.exist; + expect(bid.requestId).to.equal('263be71e91dd9f'); + expect(bid.cpm).to.equal(0.01); + expect(bid.width).to.equal(640); + expect(bid.height).to.equal(360); + }); }); - it('should have all relevant fields', () => { - const request = spec.buildRequests([ validBidReq ]); - const result = spec.interpretResponse({body: bidResponse}, request[0]); - const bid = result[0]; + describe('should support native', () => { + const request = spec.buildRequests([ validNativeBidReq ]); + const result = spec.interpretResponse({body: validNativeBidRes}, request[0]); + it('should build bid array', () => { + expect(result.length).to.equal(1); + }); + + it('should have all relevant fields', () => { + const bid = result[0]; - expect(bid.requestId).to.equal('263be71e91dd9d'); - expect(bid.cpm).to.equal(0.01); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); + expect(bid.mediaType).to.equal(NATIVE); + expect(bid.native).to.exist; + expect(bid.requestId).to.equal('263be71e91dda0'); + expect(bid.cpm).to.equal(0.01); + expect(bid.width).to.equal(1); + expect(bid.height).to.equal(1); + }); }); }); }); From 99fa86e9e1ceed1d7b95962c17e212c00ec72b8c Mon Sep 17 00:00:00 2001 From: Ryan Chou Date: Tue, 26 Jun 2018 12:08:42 +0800 Subject: [PATCH 17/27] Change request method from POST to GET --- modules/ucfunnelBidAdapter.js | 13 ++++++++----- test/spec/modules/ucfunnelBidAdapter_spec.js | 9 +-------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index 44a834c6962..6f235db87bd 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -43,13 +43,9 @@ export const spec = { buildRequests: function(bids, bidderRequest) { return bids.map(bid => { return { - method: 'POST', + method: 'GET', url: location.protocol + spec.ENDPOINT, data: getRequestData(bid, bidderRequest), - options: { - contentType: 'application/json', - withCredentials: true - }, bidRequest: bid } }); @@ -207,4 +203,11 @@ function getRequestData(bid, bidderRequest) { } return bidData; + // var bidReqParams = []; + // for (var p in bidData) { + // if (bidData.hasOwnProperty(p)) { + // bidReqParams.push(encodeURIComponent(p) + '=' + encodeURIComponent(bidData[p])); + // } + // } + // return bidReqParams.join('&'); } diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 2b774bb7e5a..b378a4ebfa5 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -100,17 +100,10 @@ describe('ucfunnel Adapter', () => { describe('build request', () => { const request = spec.buildRequests([validBannerBidReq]); it('should create a POST request for every bid', () => { - expect(request[0].method).to.equal('POST'); + expect(request[0].method).to.equal('GET'); expect(request[0].url).to.equal(location.protocol + spec.ENDPOINT); }); - it('should ensure contentType is `application/json`', () => { - expect(request[0].options).to.deep.equal({ - contentType: 'application/json', - withCredentials: true - }); - }); - it('should attach the bid request object', () => { expect(request[0].bidRequest).to.equal(validBannerBidReq); }); From 03e37e62190b43c5ad869b244372bbcb826b2ce2 Mon Sep 17 00:00:00 2001 From: Ryan Chou Date: Wed, 27 Jun 2018 09:25:44 +0800 Subject: [PATCH 18/27] Remove unnecessary comment --- modules/ucfunnelBidAdapter.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index 6f235db87bd..583744454cc 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -203,11 +203,4 @@ function getRequestData(bid, bidderRequest) { } return bidData; - // var bidReqParams = []; - // for (var p in bidData) { - // if (bidData.hasOwnProperty(p)) { - // bidReqParams.push(encodeURIComponent(p) + '=' + encodeURIComponent(bidData[p])); - // } - // } - // return bidReqParams.join('&'); } From aabfdd401dbae0448c678f4d6cb49de7502c28d5 Mon Sep 17 00:00:00 2001 From: Ryan Chou Date: Tue, 3 Jul 2018 14:25:04 +0800 Subject: [PATCH 19/27] Support vastXml and vastUrl for video request --- modules/ucfunnelBidAdapter.js | 3 ++- test/spec/modules/ucfunnelBidAdapter_spec.js | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index 583744454cc..d0ed7044242 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -95,7 +95,8 @@ export const spec = { break; case VIDEO: Object.assign(bid, { - vastXml: ad.adm + vastUrl: ad.vastUrl, + vastXml: ad.vastXml }); if (videoPlayerSize && videoPlayerSize.length === 2) { diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index b378a4ebfa5..e8a4624bf16 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -46,7 +46,8 @@ const validVideoBidReq = { const validVideoBidRes = { creative_type: VIDEO, ad_id: 'ad-9A22D466494297EAC443D967B2622DA9', - adm: 'ucX I-Primo 00:00:30', + vastUrl: 'https://ads.aralego.com/ads/58f9749f-0553-4993-8d9a-013a38b29e55', + vastXml: 'ucX I-Primo 00:00:30', cpm: 0.01, width: 640, height: 360 @@ -157,6 +158,7 @@ describe('ucfunnel Adapter', () => { const bid = result[0]; expect(bid.mediaType).to.equal(VIDEO); + expect(bid.vastUrl).to.exist; expect(bid.vastXml).to.exist; expect(bid.requestId).to.equal('263be71e91dd9f'); expect(bid.cpm).to.equal(0.01); From af05d0778927f71b131611b73637df7000a2a7c3 Mon Sep 17 00:00:00 2001 From: ucfunnel Date: Sun, 2 Dec 2018 23:24:07 +0800 Subject: [PATCH 20/27] update TTL to 30 mins --- modules/ucfunnelBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index d0ed7044242..e751dd3451c 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -68,7 +68,7 @@ export const spec = { dealId: ad.deal || null, currency: 'USD', netRevenue: true, - ttl: 1000 + ttl: 1800 }; if (ad.creative_type) { From 45614c9b96f9d40fa276dc2da4d7fa018869cc24 Mon Sep 17 00:00:00 2001 From: ucfunnel Date: Tue, 4 Dec 2018 02:28:52 +0800 Subject: [PATCH 21/27] Avoid using arrow function which is not discuraged in mocha --- test/spec/modules/ucfunnelBidAdapter_spec.js | 38 ++++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index e8a4624bf16..32daf5ecb96 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -89,34 +89,34 @@ const validNativeBidRes = { width: 1 }; -describe('ucfunnel Adapter', () => { - describe('request', () => { - it('should validate bid request', () => { +describe('ucfunnel Adapter', function () { + describe('request', function () { + it('should validate bid request', function () { expect(spec.isBidRequestValid(validBannerBidReq)).to.equal(true); }); - it('should not validate incorrect bid request', () => { + it('should not validate incorrect bid request', function () { expect(spec.isBidRequestValid(invalidBannerBidReq)).to.equal(false); }); }); - describe('build request', () => { + describe('build request', function () { const request = spec.buildRequests([validBannerBidReq]); - it('should create a POST request for every bid', () => { + it('should create a POST request for every bid', function () { expect(request[0].method).to.equal('GET'); expect(request[0].url).to.equal(location.protocol + spec.ENDPOINT); }); - it('should attach the bid request object', () => { + it('should attach the bid request object', function () { expect(request[0].bidRequest).to.equal(validBannerBidReq); }); - it('should attach request data', () => { + it('should attach request data', function () { const data = request[0].data; const [ width, height ] = validBannerBidReq.sizes[0]; expect(data.w).to.equal(width); expect(data.h).to.equal(height); }); - it('must parse bid size from a nested array', () => { + it('must parse bid size from a nested array', function () { const width = 640; const height = 480; validBannerBidReq.sizes = [[ width, height ]]; @@ -127,15 +127,15 @@ describe('ucfunnel Adapter', () => { }); }); - describe('interpretResponse', () => { - describe('should support banner', () => { + describe('interpretResponse', function () { + describe('should support banner', function () { const request = spec.buildRequests([ validBannerBidReq ]); const result = spec.interpretResponse({body: validBannerBidRes}, request[0]); - it('should build bid array for banner', () => { + it('should build bid array for banner', function () { expect(result.length).to.equal(1); }); - it('should have all relevant fields', () => { + it('should have all relevant fields', function () { const bid = result[0]; expect(bid.mediaType).to.equal(BANNER); @@ -147,14 +147,14 @@ describe('ucfunnel Adapter', () => { }); }); - describe('should support video', () => { + describe('should support video', function () { const request = spec.buildRequests([ validVideoBidReq ]); const result = spec.interpretResponse({body: validVideoBidRes}, request[0]); - it('should build bid array', () => { + it('should build bid array', function () { expect(result.length).to.equal(1); }); - it('should have all relevant fields', () => { + it('should have all relevant fields', function () { const bid = result[0]; expect(bid.mediaType).to.equal(VIDEO); @@ -167,14 +167,14 @@ describe('ucfunnel Adapter', () => { }); }); - describe('should support native', () => { + describe('should support native', function () { const request = spec.buildRequests([ validNativeBidReq ]); const result = spec.interpretResponse({body: validNativeBidRes}, request[0]); - it('should build bid array', () => { + it('should build bid array', function () { expect(result.length).to.equal(1); }); - it('should have all relevant fields', () => { + it('should have all relevant fields', function () { const bid = result[0]; expect(bid.mediaType).to.equal(NATIVE); From c22723e2351f2afcc45babc03e9b028cfca035a2 Mon Sep 17 00:00:00 2001 From: "jack.hsieh" Date: Tue, 9 Jul 2019 15:05:32 +0800 Subject: [PATCH 22/27] ucfunnel tdid support --- modules/ucfunnelBidAdapter.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index c1ac951066d..7974f053bbd 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -168,7 +168,7 @@ function getRequestData(bid, bidderRequest) { const dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; const videoContext = utils.deepAccess(bid, 'mediaTypes.video.context'); const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); - + const userIdTdid = (bid.userId && bid.userId.tdid) ? bid.userId.tdid : ''; // general bid data let bidData = { ver: VER, @@ -181,7 +181,8 @@ function getRequestData(bid, bidderRequest) { ru: ref, adid: utils.getBidIdParameter('adid', bid.params), w: size[0], - h: size[1] + h: size[1], + tdid: userIdTdid }; if (bid.mediaType === 'video' || videoMediaType) { From 0175c5729b8afbe7cfbd174d0d814114afdac275 Mon Sep 17 00:00:00 2001 From: "jack.hsieh" Date: Thu, 17 Oct 2019 17:27:16 +0800 Subject: [PATCH 23/27] ucfunnel fix error message in debug mode --- modules/ucfunnelBidAdapter.js | 9 +++++---- test/spec/modules/ucfunnelBidAdapter_spec.js | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index 7974f053bbd..6833f93bc3f 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -64,7 +64,7 @@ export const spec = { let bid = { requestId: bidRequest.bidId, cpm: ad.cpm || 0, - creativeId: ad.ad_id, + creativeId: ad.ad_id || bidRequest.params.adid, dealId: ad.deal || null, currency: 'USD', netRevenue: true, @@ -108,10 +108,11 @@ export const spec = { break; case BANNER: default: + var size = parseSizes(bidRequest); Object.assign(bid, { - width: ad.width, - height: ad.height, - ad: ad.adm + width: ad.width || size[0], + height: ad.height || size[1], + ad: ad.adm || '' }); } diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 32daf5ecb96..723f6c4ee47 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -33,6 +33,8 @@ const validBannerBidRes = { width: 300 }; +const invalidBannerBidRes = ''; + const validVideoBidReq = { bidder: BIDDER_CODE, params: { @@ -147,6 +149,24 @@ describe('ucfunnel Adapter', function () { }); }); + describe('handle banner no ad', function () { + const request = spec.buildRequests([ validBannerBidReq ]); + const result = spec.interpretResponse({body: invalidBannerBidRes}, request[0]); + it('should build bid array for banner', function () { + expect(result.length).to.equal(1); + }); + + it('should have all relevant fields', function () { + const bid = result[0]; + + expect(bid.ad).to.exist; + expect(bid.requestId).to.equal('263be71e91dd9d'); + expect(bid.cpm).to.equal(0); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + }); + }); + describe('should support video', function () { const request = spec.buildRequests([ validVideoBidReq ]); const result = spec.interpretResponse({body: validVideoBidRes}, request[0]); From c09b8162cde8eba3ab3d29d2d633809d6d5aa02e Mon Sep 17 00:00:00 2001 From: "jack.hsieh" Date: Mon, 25 Nov 2019 15:22:14 +0800 Subject: [PATCH 24/27] ucfunnel adapter add bidfloor parameter --- modules/ucfunnelBidAdapter.js | 6 +++- test/spec/modules/ucfunnelBidAdapter_spec.js | 33 +++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index 43c125c2a96..f967f30bd44 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -71,6 +71,9 @@ export const spec = { ttl: 1800 }; + if (bidRequest.params && bidRequest.params.bidfloor && ad.cpm && ad.cpm < bidRequest.params.bidfloor) { + bid.cpm = 0; + } if (ad.creative_type) { bid.mediaType = ad.creative_type; } @@ -207,7 +210,8 @@ function getRequestData(bid, bidderRequest) { w: size[0], h: size[1], tdid: userIdTdid, - schain: supplyChain + schain: supplyChain, + fp: utils.getBidIdParameter('bidfloor', bid.params) }; if (bid.mediaType === 'video' || videoMediaType) { diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 617f4bb69e8..bebd780a587 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -7,7 +7,8 @@ const BIDDER_CODE = 'ucfunnel'; const validBannerBidReq = { bidder: BIDDER_CODE, params: { - adid: 'ad-34BBD2AA24B678BBFD4E7B9EE3B872D' + adid: 'ad-34BBD2AA24B678BBFD4E7B9EE3B872D', + bidfloor: 1.0 }, sizes: [[300, 250]], bidId: '263be71e91dd9d', @@ -42,7 +43,7 @@ const validBannerBidRes = { creative_type: BANNER, ad_id: 'ad-34BBD2AA24B678BBFD4E7B9EE3B872D', adm: '
', - cpm: 0.01, + cpm: 1.01, height: 250, width: 300 }; @@ -64,7 +65,7 @@ const validVideoBidRes = { ad_id: 'ad-9A22D466494297EAC443D967B2622DA9', vastUrl: 'https://ads.aralego.com/ads/58f9749f-0553-4993-8d9a-013a38b29e55', vastXml: 'ucX I-Primo 00:00:30', - cpm: 0.01, + cpm: 1.01, width: 640, height: 360 }; @@ -100,7 +101,7 @@ const validNativeBidRes = { clickUrl: 'https://www.ucfunnel.com', impressionTrackers: ['https://www.aralego.net/imp?mf=native&adid=ad-9A22D466494297EAC443D967B2622DA9&auc=9ad1fa8d-2297-4660-a018-b39945054746'], }, - cpm: 0.01, + cpm: 1.01, height: 1, width: 1 }; @@ -158,7 +159,7 @@ describe('ucfunnel Adapter', function () { expect(bid.mediaType).to.equal(BANNER); expect(bid.ad).to.exist; expect(bid.requestId).to.equal('263be71e91dd9d'); - expect(bid.cpm).to.equal(0.01); + expect(bid.cpm).to.equal(1.01); expect(bid.width).to.equal(300); expect(bid.height).to.equal(250); }); @@ -182,6 +183,24 @@ describe('ucfunnel Adapter', function () { }); }); + describe('handle banner cpm under bidfloor', function () { + const request = spec.buildRequests([ validBannerBidReq ]); + const result = spec.interpretResponse({body: invalidBannerBidRes}, request[0]); + it('should build bid array for banner', function () { + expect(result.length).to.equal(1); + }); + + it('should have all relevant fields', function () { + const bid = result[0]; + + expect(bid.ad).to.exist; + expect(bid.requestId).to.equal('263be71e91dd9d'); + expect(bid.cpm).to.equal(0); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + }); + }); + describe('should support video', function () { const request = spec.buildRequests([ validVideoBidReq ]); const result = spec.interpretResponse({body: validVideoBidRes}, request[0]); @@ -196,7 +215,7 @@ describe('ucfunnel Adapter', function () { expect(bid.vastUrl).to.exist; expect(bid.vastXml).to.exist; expect(bid.requestId).to.equal('263be71e91dd9f'); - expect(bid.cpm).to.equal(0.01); + expect(bid.cpm).to.equal(1.01); expect(bid.width).to.equal(640); expect(bid.height).to.equal(360); }); @@ -215,7 +234,7 @@ describe('ucfunnel Adapter', function () { expect(bid.mediaType).to.equal(NATIVE); expect(bid.native).to.exist; expect(bid.requestId).to.equal('263be71e91dda0'); - expect(bid.cpm).to.equal(0.01); + expect(bid.cpm).to.equal(1.01); expect(bid.width).to.equal(1); expect(bid.height).to.equal(1); }); From fee3803cd0b8ebfe7c2ef1b3ba65361403fa9c6c Mon Sep 17 00:00:00 2001 From: "jack.hsieh" Date: Thu, 5 Dec 2019 13:20:33 +0800 Subject: [PATCH 25/27] ucfunnel adapter support CCPA --- modules/ucfunnelBidAdapter.js | 6 ++++++ test/spec/modules/ucfunnelBidAdapter_spec.js | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index f967f30bd44..b846591c129 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -214,6 +214,12 @@ function getRequestData(bid, bidderRequest) { fp: utils.getBidIdParameter('bidfloor', bid.params) }; + if (bidderRequest && bidderRequest.uspConsent) { + Object.assign(bidData, { + usprivacy: bidderRequest.uspConsent + }); + } + if (bid.mediaType === 'video' || videoMediaType) { switch (videoContext) { case 'outstream': diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index bebd780a587..9d44f1030ba 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -4,6 +4,11 @@ import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes'; const URL = '//hb.aralego.com/header'; const BIDDER_CODE = 'ucfunnel'; + +const bidderRequest = { + uspConsent: '1YNN' +}; + const validBannerBidReq = { bidder: BIDDER_CODE, params: { @@ -116,7 +121,7 @@ describe('ucfunnel Adapter', function () { }); }); describe('build request', function () { - const request = spec.buildRequests([validBannerBidReq]); + const request = spec.buildRequests([validBannerBidReq], bidderRequest); it('should create a POST request for every bid', function () { expect(request[0].method).to.equal('GET'); expect(request[0].url).to.equal(location.protocol + spec.ENDPOINT); @@ -129,6 +134,7 @@ describe('ucfunnel Adapter', function () { it('should attach request data', function () { const data = request[0].data; const [ width, height ] = validBannerBidReq.sizes[0]; + expect(data.usprivacy).to.equal('1YNN'); expect(data.w).to.equal(width); expect(data.h).to.equal(height); expect(data.schain).to.equal('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com'); From 084190b4bb811ffaffc5aaf3823053940c854ff0 Mon Sep 17 00:00:00 2001 From: "jack.hsieh" Date: Fri, 10 Jan 2020 12:03:46 +0800 Subject: [PATCH 26/27] ucfunnel adapter native support clicktrackers --- modules/ucfunnelBidAdapter.js | 1 + test/spec/modules/ucfunnelBidAdapter_spec.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index ecb1681404e..76d423a40cd 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -90,6 +90,7 @@ export const spec = { image: nativeAd.image || nativeAd.image.url, icon: nativeAd.icon || nativeAd.icon.url, clickUrl: nativeAd.clickUrl, + clickTrackers: (nativeAd.clicktrackers) ? nativeAd.clicktrackers : [], impressionTrackers: nativeAd.impressionTrackers, } }); diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 529f647981c..38d86e7d808 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -104,6 +104,7 @@ const validNativeBidRes = { heigh: 84 }, clickUrl: 'https://www.ucfunnel.com', + clicktrackers: ['https://dev-ad-track.aralego.com/v1/nat/click?iid=72165d02-408a-470c-bb52-ae7d7b0a4549'], impressionTrackers: ['https://www.aralego.net/imp?mf=native&adid=ad-9A22D466494297EAC443D967B2622DA9&auc=9ad1fa8d-2297-4660-a018-b39945054746'], }, cpm: 1.01, @@ -244,6 +245,8 @@ describe('ucfunnel Adapter', function () { expect(bid.cpm).to.equal(1.01); expect(bid.width).to.equal(1); expect(bid.height).to.equal(1); + expect(bid.native.clickUrl).to.equal('https://www.ucfunnel.com'); + expect(bid.native.clickTrackers[0]).to.equal('https://dev-ad-track.aralego.com/v1/nat/click?iid=72165d02-408a-470c-bb52-ae7d7b0a4549'); }); }); }); From bb22940939a90f0cae184d05b969eb6f8c59d10d Mon Sep 17 00:00:00 2001 From: "jack.hsieh" Date: Fri, 17 Jan 2020 12:39:23 +0800 Subject: [PATCH 27/27] ucfunnel adapter change cookie sync setting --- modules/ucfunnelBidAdapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index fc6af87e692..e2c642862fd 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -125,7 +125,7 @@ export const spec = { if (syncOptions.iframeEnabled) { return [{ type: 'iframe', - url: 'https://cdn.aralego.com/ucfad/cookie/sync.html' + url: 'https://cdn.aralego.net/ucfad/cookie/sync.html' }]; } else if (syncOptions.pixelEnabled) { return [{