From 9fc81d28489c38a753309736219274effedb10b6 Mon Sep 17 00:00:00 2001 From: mcallari Date: Tue, 17 Oct 2017 15:20:30 -0400 Subject: [PATCH 1/4] Optimera Adapter for 1.0 (#1759) --- modules/optimeraBidAdapter.js | 75 ++++++++++++++++++ modules/optimeraBidAdapter.md | 40 ++++++++++ test/spec/modules/optimeraBidAdapter_spec.js | 80 ++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 modules/optimeraBidAdapter.js create mode 100644 modules/optimeraBidAdapter.md create mode 100644 test/spec/modules/optimeraBidAdapter_spec.js diff --git a/modules/optimeraBidAdapter.js b/modules/optimeraBidAdapter.js new file mode 100644 index 00000000000..540b98d2986 --- /dev/null +++ b/modules/optimeraBidAdapter.js @@ -0,0 +1,75 @@ +import {registerBidder} from 'src/adapters/bidderFactory'; +const BIDDER_CODE = 'optimera'; +const SCORES_BASE_URL = 'https://s3.amazonaws.com/elasticbeanstalk-us-east-1-397719490216/json/client/'; + +export const spec = { + code: BIDDER_CODE, + /** + * Determines whether or not the given bid request is valid. + * + * @param {bidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bidRequest) { + return !!(bidRequest.params.custom.clientID); + }, + /** + * Make a server request from the list of BidRequests. + * + * @param {validBidRequests[]} - an array of bids + * @return ServerRequest Info describing the request to the server. + */ + buildRequests: function (validBidRequests) { + var optimeraHost = window.location.host; + var optimeraPathName = window.location.pathname; + var timestamp = Math.round(new Date().getTime() / 1000); + var clientID = validBidRequests[0].params.custom.clientID; + var oDv = []; + if (clientID != undefined) { + oDv.push(clientID); + for (var i = 0; i < validBidRequests.length; i++) { + oDv.push(validBidRequests[i].placementCode); + } + window.oDv = oDv; + var scoresURL = SCORES_BASE_URL + clientID + '/' + optimeraHost + optimeraPathName + '.js'; + return { + method: 'GET', + url: scoresURL, + payload: validBidRequests, + data: {'t': timestamp} + }; + } + }, + /** + * 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, bidRequest) { + var scores = serverResponse.replace('window.oVa = ', ''); + scores = scores.replace(';', ''); + scores = JSON.parse(scores); + var validBids = bidRequest.payload; + var bidResponses = []; + var dealId = ''; + for (var i = 0; i < validBids.length; i++) { + if (validBids[i].placementCode in scores && validBids[i].params.custom.clientID != undefined) { + dealId = scores[validBids[i].placementCode]; + } + var bidResponse = { + bidderCode: spec.code, + requestId: validBids[i].bidId, + ad: '
', + cpm: 0.01, + width: 0, + height: 0, + dealId: dealId + }; + bidResponses.push(bidResponse); + } + return bidResponses; + } +} + +registerBidder(spec); diff --git a/modules/optimeraBidAdapter.md b/modules/optimeraBidAdapter.md new file mode 100644 index 00000000000..d8a196372be --- /dev/null +++ b/modules/optimeraBidAdapter.md @@ -0,0 +1,40 @@ +# Overview + +``` +Module Name: Optimera Bidder Adapter +Module Type: Bidder Adapter +Maintainer: kcandiotti@optimera.nyc +``` + +# Description + +Module that adds ad placement visibility scores for DFP. + +# Test Parameters +``` + var adUnits = [{ + code: 'div-1', + sizes: [[300, 250], [300,600]], + bids: [ + { + bidder: 'optimera', + params: { + custom:{ + clientID: '0' + } + } + }] + },{ + code: 'div-0', + sizes: [[728, 90]], + bids: [ + { + bidder: 'optimera', + params: { + custom:{ + clientID: '0' + } + } + }] + }]; +``` diff --git a/test/spec/modules/optimeraBidAdapter_spec.js b/test/spec/modules/optimeraBidAdapter_spec.js new file mode 100644 index 00000000000..0ca3d00676a --- /dev/null +++ b/test/spec/modules/optimeraBidAdapter_spec.js @@ -0,0 +1,80 @@ +import { expect } from 'chai'; +import { spec } from 'modules/optimeraBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; + +describe('OptimeraAdapter', () => { + const adapter = newBidder(spec); + + describe('inherited functions', () => { + it('exists and is a function', () => { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }) + + describe('isBidRequestValid', () => { + let bid = { + 'bidder': 'optimera', + 'params': { + 'custom': { + 'clientID': '0' + } + }, + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250], [300, 600]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + + it('should return true when required params found', () => { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + }) + + describe('buildRequests', () => { + let validBidRequests = [ + { + 'adUnitCode': 'div-0', + 'auctionId': '1ab30503e03994', + 'bidId': '313e0afede8cdb', + 'bidder': 'optimera', + 'bidderRequestId': '202be1ce3f6194', + 'params': { + 'placementCode': '0', + 'placementId': '104333943', + 'custom': { + 'clientId': '0' + } + } + } + ]; + it('buildRequests fires', () => { + var request = spec.buildRequests(validBidRequests); + }); + }) + + describe('interpretResponse', () => { + let serverResponse = 'window.oVa = {"div-0":["RB_K","728x90K"], "div-1":["RB_K","300x250K", "300x600K"], "timestamp":["RB_K","1507565666"]};'; + var bidRequest = { + 'method': 'get', + 'payload': [ + { + 'bidder': 'optimera', + 'params': { + 'placementId': '10433943', + 'placementCode': '0', + 'custom': { + 'clientID': '0' + } + }, + 'adUnitCode': 'div-0', + 'bidId': '307440db8538ab' + } + ] + } + it('interpresResponse fires', () => { + window.oDv = window.oDv || []; + var bidResponses = spec.interpretResponse(serverResponse, bidRequest); + }); + }); +}); From a0d99c5c326f22ceef822cdfff89cd4d5ec38d42 Mon Sep 17 00:00:00 2001 From: mcallari Date: Wed, 1 Nov 2017 16:59:06 -0400 Subject: [PATCH 2/4] Optimera adapter var checks and assertions (#1759) --- modules/optimeraBidAdapter.js | 47 +++++++++++++------- test/spec/modules/optimeraBidAdapter_spec.js | 23 +++++----- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/modules/optimeraBidAdapter.js b/modules/optimeraBidAdapter.js index 540b98d2986..9953f3b2e16 100644 --- a/modules/optimeraBidAdapter.js +++ b/modules/optimeraBidAdapter.js @@ -11,7 +11,11 @@ export const spec = { * @return boolean True if this is a valid bid, and false otherwise. */ isBidRequestValid: function (bidRequest) { - return !!(bidRequest.params.custom.clientID); + if (typeof bidRequest.params.custom != 'undefined' && typeof bidRequest.params.custom.clientID != 'undefined') { + return true; + } else { + return false; + } }, /** * Make a server request from the list of BidRequests. @@ -23,12 +27,12 @@ export const spec = { var optimeraHost = window.location.host; var optimeraPathName = window.location.pathname; var timestamp = Math.round(new Date().getTime() / 1000); - var clientID = validBidRequests[0].params.custom.clientID; var oDv = []; - if (clientID != undefined) { + if (typeof validBidRequests[0].params.custom.clientID != 'undefined') { + var clientID = validBidRequests[0].params.custom.clientID; oDv.push(clientID); for (var i = 0; i < validBidRequests.length; i++) { - oDv.push(validBidRequests[i].placementCode); + oDv.push(validBidRequests[i].adUnitCode); } window.oDv = oDv; var scoresURL = SCORES_BASE_URL + clientID + '/' + optimeraHost + optimeraPathName + '.js'; @@ -43,30 +47,39 @@ export const spec = { /** * Unpack the response from the server into a list of bids. * + * Some required bid params are not needed for this so default + * values are used. + * * @param {*} serverResponse A successful response from the server. * @return {Bid[]} An array of bids which were nested inside the server. */ interpretResponse: function (serverResponse, bidRequest) { - var scores = serverResponse.replace('window.oVa = ', ''); + var scores = serverResponse.body.replace('window.oVa = ', ''); scores = scores.replace(';', ''); scores = JSON.parse(scores); var validBids = bidRequest.payload; var bidResponses = []; var dealId = ''; for (var i = 0; i < validBids.length; i++) { - if (validBids[i].placementCode in scores && validBids[i].params.custom.clientID != undefined) { - dealId = scores[validBids[i].placementCode]; + if (typeof validBids[i].params.custom.clientID != 'undefined') { + if (validBids[i].adUnitCode in scores) { + dealId = scores[validBids[i].adUnitCode]; + } + var bidResponse = { + bidderCode: spec.code, + requestId: validBids[i].bidId, + ad: '
', + cpm: 0.01, + width: 0, + height: 0, + dealId: dealId, + ttl: 300, + creativeId: '1', + netRevenue: '0', + currency: 'USD' + }; + bidResponses.push(bidResponse); } - var bidResponse = { - bidderCode: spec.code, - requestId: validBids[i].bidId, - ad: '
', - cpm: 0.01, - width: 0, - height: 0, - dealId: dealId - }; - bidResponses.push(bidResponse); } return bidResponses; } diff --git a/test/spec/modules/optimeraBidAdapter_spec.js b/test/spec/modules/optimeraBidAdapter_spec.js index 0ca3d00676a..57d43957874 100644 --- a/test/spec/modules/optimeraBidAdapter_spec.js +++ b/test/spec/modules/optimeraBidAdapter_spec.js @@ -19,7 +19,7 @@ describe('OptimeraAdapter', () => { 'clientID': '0' } }, - 'adUnitCode': 'adunit-code', + 'adUnitCode': 'div-0', 'sizes': [[300, 250], [300, 600]], 'bidId': '30b31c1838de1e', 'bidderRequestId': '22edbae2733bf6', @@ -32,7 +32,7 @@ describe('OptimeraAdapter', () => { }) describe('buildRequests', () => { - let validBidRequests = [ + let bid = [ { 'adUnitCode': 'div-0', 'auctionId': '1ab30503e03994', @@ -40,29 +40,30 @@ describe('OptimeraAdapter', () => { 'bidder': 'optimera', 'bidderRequestId': '202be1ce3f6194', 'params': { - 'placementCode': '0', - 'placementId': '104333943', 'custom': { - 'clientId': '0' + 'clientID': '0' } } } ]; it('buildRequests fires', () => { - var request = spec.buildRequests(validBidRequests); + let request = spec.buildRequests(bid); + expect(request).to.exist; + expect(request.method).to.equal('GET'); + expect(request.payload).to.exist; + expect(request.data.t).to.exist; }); }) describe('interpretResponse', () => { - let serverResponse = 'window.oVa = {"div-0":["RB_K","728x90K"], "div-1":["RB_K","300x250K", "300x600K"], "timestamp":["RB_K","1507565666"]};'; + let serverResponse = {}; + serverResponse.body = 'window.oVa = {"div-0":["RB_K","728x90K"], "timestamp":["RB_K","1507565666"]};'; var bidRequest = { 'method': 'get', 'payload': [ { 'bidder': 'optimera', 'params': { - 'placementId': '10433943', - 'placementCode': '0', 'custom': { 'clientID': '0' } @@ -74,7 +75,9 @@ describe('OptimeraAdapter', () => { } it('interpresResponse fires', () => { window.oDv = window.oDv || []; - var bidResponses = spec.interpretResponse(serverResponse, bidRequest); + let bidResponses = spec.interpretResponse(serverResponse, bidRequest); + expect(bidResponses[0].dealId[0]).to.equal('RB_K'); + expect(bidResponses[0].dealId[1]).to.equal('728x90K'); }); }); }); From a7dee8518172dd2ba79b2e123772dc76481963d3 Mon Sep 17 00:00:00 2001 From: mcallari Date: Mon, 20 Nov 2017 10:15:03 -0500 Subject: [PATCH 3/4] Optimera adaptor removing window global (#1759) --- modules/optimeraBidAdapter.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/optimeraBidAdapter.js b/modules/optimeraBidAdapter.js index 9953f3b2e16..8964b74e5c3 100644 --- a/modules/optimeraBidAdapter.js +++ b/modules/optimeraBidAdapter.js @@ -27,14 +27,8 @@ export const spec = { var optimeraHost = window.location.host; var optimeraPathName = window.location.pathname; var timestamp = Math.round(new Date().getTime() / 1000); - var oDv = []; if (typeof validBidRequests[0].params.custom.clientID != 'undefined') { var clientID = validBidRequests[0].params.custom.clientID; - oDv.push(clientID); - for (var i = 0; i < validBidRequests.length; i++) { - oDv.push(validBidRequests[i].adUnitCode); - } - window.oDv = oDv; var scoresURL = SCORES_BASE_URL + clientID + '/' + optimeraHost + optimeraPathName + '.js'; return { method: 'GET', From 54cd78f1980a2324a4dad265f50297c6566e8a2e Mon Sep 17 00:00:00 2001 From: mcallari Date: Tue, 5 Dec 2017 17:00:38 -0500 Subject: [PATCH 4/4] Optimera adaptor removing bidderCode property. (#1759) --- modules/optimeraBidAdapter.js | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/optimeraBidAdapter.js b/modules/optimeraBidAdapter.js index 8964b74e5c3..e77526cfdf1 100644 --- a/modules/optimeraBidAdapter.js +++ b/modules/optimeraBidAdapter.js @@ -60,7 +60,6 @@ export const spec = { dealId = scores[validBids[i].adUnitCode]; } var bidResponse = { - bidderCode: spec.code, requestId: validBids[i].bidId, ad: '
', cpm: 0.01,