-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Quantcast adaptor #1063
Merged
Merged
Quantcast adaptor #1063
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
2fca458
Initial code
ShreeniwasIyer 8b47e0f
First cut of the adapter
ShreeniwasIyer 470e5c1
Merge branch 'master' of https://github.com/prebid/Prebid.js into qcx…
ShreeniwasIyer 5292542
Renaming for consistency
ShreeniwasIyer 456ed26
Indendation and syntax changes
ShreeniwasIyer 58b294a
request processing has been completed
ShreeniwasIyer bb6a711
Merge branch 'master' of github.corp.qc:qc/INVENTORY-prebid.js into q…
ShreeniwasIyer 584d8f0
Further testing
ShreeniwasIyer 6459e39
Merge branch 'master' of github.corp.qc:qc/INVENTORY-prebid.js into q…
ShreeniwasIyer 70edd91
Switched to using Placement Code
ShreeniwasIyer 881fb06
Renamed the fields of request and response to be more consistent with…
ShreeniwasIyer b79c82b
Merge branch 'master' of github.corp.qc:qc/INVENTORY-prebid.js into q…
ShreeniwasIyer 2c5f386
Added Unit tests
ShreeniwasIyer 3534d42
Merging with Public master
ShreeniwasIyer 1ea9bce
Changed the URL
ShreeniwasIyer d05db9e
Fixed nit:spacing issues
ShreeniwasIyer 1a0e9a6
Added fix for the case when request is not found for whatever reason …
ShreeniwasIyer a7f11c9
nit being resolved
ShreeniwasIyer 4c2c8c7
Addressing comments
ShreeniwasIyer 22b6741
Fixed the indentation as per jshint errors on travis-ci build
ShreeniwasIyer 35e6574
Merge branch 'master' of github.com:prebid/Prebid.js into qcx_adaptor
ShreeniwasIyer 6885f2a
Replacing qcx with Quantcast and changing URL
ShreeniwasIyer 43b41fa
removed use of internal constants
ShreeniwasIyer 9be543b
Use getBidRequest
ShreeniwasIyer b87ab34
Pass bidRequest as second param
ShreeniwasIyer 4395bf3
Wrapping the JSON parse in try/catch
ShreeniwasIyer bbb5f16
Replacing pbjs use to 681PREBID_GLOBAL681
ShreeniwasIyer 5049ef1
Fixing JSHint errors
ShreeniwasIyer 0d92aed
Replacing array wrapping with parseSizesInput usage to make it cleaner
ShreeniwasIyer 8442e44
Fixed the error, not caught in gulp test
ShreeniwasIyer a36db04
No need to compare to undefined since as per new code, we only need t…
ShreeniwasIyer 2b28a4e
Fixed the warning
ShreeniwasIyer c8a401c
integration testing and adding quantcast to the demo html page
ShreeniwasIyer ce6118d
Merge branch 'master' into qcx_adaptor
ShreeniwasIyer 35f328a
Converting sizes into an object and removing the single size object
ShreeniwasIyer 64bbbdc
Merge branch 'qcx_adaptor' of github.com:ShreeniwasIyer/Prebid.js int…
ShreeniwasIyer f8f0baa
Added withCredentials variable to AJAX calls
ShreeniwasIyer fae67ac
using placement code as the key
ShreeniwasIyer 8e3a19a
Adding the bidder code and request id to responseBid
ShreeniwasIyer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ | |
"pubmatic", | ||
"pulsepoint", | ||
"pulsepointLite", | ||
"quantcast", | ||
"rhythmone", | ||
"rubicon", | ||
"smartyads", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
const utils = require('../utils.js'); | ||
const bidfactory = require('../bidfactory.js'); | ||
const bidmanager = require('../bidmanager.js'); | ||
const ajax = require('../ajax.js'); | ||
const CONSTANTS = require('../constants.json'); | ||
const QUANTCAST_CALLBACK_URL = 'http://global.qc.rtb.quantserve.com:8080/qchb'; | ||
|
||
var QuantcastAdapter = function QuantcastAdapter() { | ||
|
||
const BIDDER_CODE = 'quantcast'; | ||
|
||
const DEFAULT_BID_FLOOR = 0.0000000001; | ||
let bidRequests = {}; | ||
|
||
let returnEmptyBid = function(bidId) { | ||
var bidRequested = utils.getBidRequest(bidId); | ||
if (!utils.isEmpty(bidRequested)) { | ||
let bid = bidfactory.createBid(CONSTANTS.STATUS.NO_BID, bidRequested); | ||
bid.bidderCode = BIDDER_CODE; | ||
bidmanager.addBidResponse(bidRequested.placementCode, bid); | ||
} | ||
return; | ||
}; | ||
|
||
|
||
//expose the callback to the global object: | ||
$$PREBID_GLOBAL$$.handleQuantcastCB = function (responseText) { | ||
if(utils.isEmpty(responseText)) { | ||
return; | ||
} | ||
let response = null; | ||
try { | ||
response = JSON.parse(responseText); | ||
} catch(e) { | ||
// Malformed JSON | ||
utils.logError("Malformed JSON received from server - can't do anything here"); | ||
return; | ||
} | ||
|
||
if(response === null || !response.hasOwnProperty('bids') || utils.isEmpty(response.bids)) { | ||
utils.logError("Sub-optimal JSON received from server - can't do anything here"); | ||
return; | ||
} | ||
|
||
for(let i = 0; i < response.bids.length; i++) { | ||
let seatbid = response.bids[i]; | ||
let key = seatbid.placementCode; | ||
var request = bidRequests[key]; | ||
if(request === null || request === undefined) { | ||
return returnEmptyBid(seatbid.placementCode); | ||
} | ||
// This line is required since this is the field | ||
// that bidfactory.createBid looks for | ||
request.bidId = request.imp[0].placementCode; | ||
let responseBid = bidfactory.createBid(CONSTANTS.STATUS.GOOD, request); | ||
|
||
responseBid.cpm = seatbid.cpm; | ||
responseBid.ad = seatbid.ad; | ||
responseBid.height = seatbid.height; | ||
responseBid.width = seatbid.width; | ||
responseBid.bidderCode = response.bidderCode; | ||
responseBid.requestId = request.requestId; | ||
responseBid.bidderCode = BIDDER_CODE; | ||
|
||
bidmanager.addBidResponse(request.bidId, responseBid); | ||
} | ||
|
||
}; | ||
|
||
function callBids(params) { | ||
let bids = params.bids || []; | ||
if (bids.length === 0) { | ||
return; | ||
} | ||
|
||
let referrer = utils.getTopWindowUrl(); | ||
let loc = utils.getTopWindowLocation(); | ||
let domain = loc.hostname; | ||
let publisherId = 0; | ||
|
||
publisherId = '' + bids[0].params.publisherId; | ||
utils._each(bids, function(bid) { | ||
let key = bid.placementCode; | ||
var bidSizes = []; | ||
utils._each(bid.sizes, function (size) { | ||
bidSizes.push({ | ||
'width' : size[0], | ||
'height' : size[1] | ||
}); | ||
}); | ||
|
||
bidRequests[key] = bidRequests[key] || { | ||
'publisherId' : publisherId, | ||
'requestId' : bid.bidId, | ||
'bidId' : bid.bidId, | ||
'site' : { | ||
'page' : loc.href, | ||
'referrer' : referrer, | ||
'domain' : domain, | ||
}, | ||
'imp' : [{ | ||
|
||
'banner' : { | ||
'battr' : bid.params.battr, | ||
'sizes' : bidSizes, | ||
}, | ||
'placementCode' : bid.placementCode, | ||
'bidFloor' : bid.params.bidFloor || DEFAULT_BID_FLOOR, | ||
}] | ||
}; | ||
|
||
utils._each(bidRequests, function (bidRequest) { | ||
ajax.ajax(QUANTCAST_CALLBACK_URL, $$PREBID_GLOBAL$$.handleQuantcastCB, JSON.stringify(bidRequest), { | ||
method : 'POST', | ||
withCredentials: true | ||
}); | ||
}); | ||
}); | ||
} | ||
|
||
|
||
// Export the `callBids` function, so that Prebid.js can execute | ||
// this function when the page asks to send out bid requests. | ||
return { | ||
callBids: callBids, | ||
QUANTCAST_CALLBACK_URL: QUANTCAST_CALLBACK_URL | ||
}; | ||
}; | ||
|
||
exports.createNew = function() { | ||
return new QuantcastAdapter(); | ||
}; | ||
|
||
|
||
module.exports = QuantcastAdapter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import {expect} from 'chai'; | ||
import Adapter from '../../../src/adapters/quantcast'; | ||
import * as ajax from 'src/ajax'; | ||
import bidManager from '../../../src/bidmanager'; | ||
import adLoader from '../../../src/adloader'; | ||
|
||
describe('quantcast adapter', () => { | ||
|
||
let bidsRequestedOriginal; | ||
let adapter; | ||
let sandbox; | ||
let ajaxStub; | ||
|
||
const bidderRequest = { | ||
bidderCode: 'quantcast', | ||
requestId : "595ffa73-d78a-46c9-b18e-f99548a5be6b", | ||
bidderRequestId:"1cc026909c24c8", | ||
bids: [ | ||
{ | ||
bidId: '2f7b179d443f14', | ||
bidder: 'quantcast', | ||
placementCode: 'div-gpt-ad-1438287399331-0', | ||
sizes: [[300,250],[300,600]], | ||
params: { | ||
publisherId: 'test-publisher', | ||
battr : [1,2], | ||
} | ||
} | ||
] | ||
}; | ||
|
||
beforeEach(() => { | ||
bidsRequestedOriginal = $$PREBID_GLOBAL$$._bidsRequested; | ||
$$PREBID_GLOBAL$$._bidsRequested = []; | ||
|
||
adapter = new Adapter(); | ||
sandbox = sinon.sandbox.create(); | ||
ajaxStub = sandbox.stub(ajax, 'ajax'); | ||
}); | ||
|
||
afterEach(() => { | ||
sandbox.restore(); | ||
|
||
$$PREBID_GLOBAL$$._bidsRequested = bidsRequestedOriginal; | ||
}); | ||
|
||
describe('sizes', () => { | ||
let bidderRequest = { | ||
bidderCode: 'quantcast', | ||
requestId : "595ffa73-d78a-46c9-b18e-f99548a5be6b", | ||
bidderRequestId:"1cc026909c24c8", | ||
bids: [ | ||
{ | ||
bidId: '2f7b179d443f14', | ||
bidder: 'quantcast', | ||
placementCode: 'div-gpt-ad-1438287399331-0', | ||
sizes: [[300,250],[300,600]], | ||
params: { | ||
publisherId: 'test-publisher', | ||
battr : [1,2], | ||
} | ||
} | ||
] | ||
}; | ||
|
||
it('should not call server when empty input is provided', () => { | ||
adapter.callBids({}); | ||
sinon.assert.notCalled(ajaxStub); | ||
}); | ||
|
||
it('should call server once even when multiple sizes are passed', () => { | ||
adapter.callBids(bidderRequest); | ||
sinon.assert.calledOnce(ajaxStub); | ||
|
||
expect(ajaxStub.firstCall.args[0]).to.eql(adapter.QUANTCAST_CALLBACK_URL); | ||
expect(ajaxStub.firstCall.args[1]).to.exist.and.to.be.a('function'); | ||
expect(ajaxStub.firstCall.args[2]).to.include('div-gpt-ad-1438287399331-0'); | ||
expect(ajaxStub.firstCall.args[2]).to.include('test-publisher'); | ||
expect(ajaxStub.firstCall.args[2]).to.include('2f7b179d443f14'); | ||
expect(ajaxStub.firstCall.args[3]).to.eql({method : 'POST', withCredentials: true}); | ||
}); | ||
|
||
it('should call server once when one size is passed', () => { | ||
bidderRequest.bids[0].sizes = [728, 90]; | ||
adapter.callBids(bidderRequest); | ||
sinon.assert.calledOnce(ajaxStub); | ||
|
||
expect(ajaxStub.firstCall.args[0]).to.eql(adapter.QUANTCAST_CALLBACK_URL); | ||
expect(ajaxStub.firstCall.args[1]).to.exist.and.to.be.a('function'); | ||
expect(ajaxStub.firstCall.args[3]).to.eql({method : 'POST', withCredentials: true}); | ||
}); | ||
|
||
it('should call server once when size is passed as string', () => { | ||
bidderRequest.bids[0].sizes = "728x90"; | ||
adapter.callBids(bidderRequest); | ||
sinon.assert.calledOnce(ajaxStub); | ||
|
||
expect(ajaxStub.firstCall.args[0]).to.eql(adapter.QUANTCAST_CALLBACK_URL); | ||
expect(ajaxStub.firstCall.args[1]).to.exist.and.to.be.a('function'); | ||
expect(ajaxStub.firstCall.args[3]).to.eql({method : 'POST', withCredentials: true}); | ||
}); | ||
|
||
it('should call server once when sizes are passed as a comma-separated string', () => { | ||
bidderRequest.bids[0].sizes = "728x90,360x240"; | ||
adapter.callBids(bidderRequest); | ||
sinon.assert.calledOnce(ajaxStub); | ||
|
||
expect(ajaxStub.firstCall.args[0]).to.eql(adapter.QUANTCAST_CALLBACK_URL); | ||
expect(ajaxStub.firstCall.args[1]).to.exist.and.to.be.a('function'); | ||
expect(ajaxStub.firstCall.args[3]).to.eql({method : 'POST', withCredentials: true}); | ||
}); | ||
|
||
|
||
}); | ||
|
||
describe('handleQuantcastCB add bids to the manager', () => { | ||
|
||
let firstBid; | ||
let addBidReponseStub; | ||
let bidsRequestedOriginal; | ||
// respond | ||
let bidderReponse = { | ||
"bidderCode": "quantcast", | ||
"requestId" : bidderRequest.requestId, | ||
"bids" : [ | ||
{ | ||
"statusCode" : 1, | ||
"placementCode" : bidderRequest.bids[0].bidId, | ||
"cpm": 4.5, | ||
"ad": "<!DOCTYPE html>\n\n\n<div style=\"height: 250; width: 300; display: table-cell; vertical-align: middle;\">\n<div style=\"width: 300px; margin-left: auto; margin-right: auto;\"> \n\n <script src=\"https://adserver.adtechus.com/addyn/3.0/5399.1/2394397/0/-1/QUANTCAST;size=300x250;target=_blank;alias=;kvp36=;sub1=;kvl=;kvc=;kvs=300x250;kvi=;kva=;sub2=;rdclick=http://exch.quantserve.com/r?a=;labels=_qc.clk,_click.adserver.rtb,_click.rand.;rtbip=;rtbdata2=;redirecturl2=\" type=\"text/javascript\"></script>\n\n<img src=\"https://exch.quantserve.com/pixel/p_12345.gif?media=ad&p=&r=&rand=&labels=_qc.imp,_imp.adserver.rtb&rtbip=&rtbdata2=\" style=\"display: none;\" border=\"0\" height=\"1\" width=\"1\" alt=\"Quantcast\"/>\n\n</div>\n</div>", | ||
"width": 300, | ||
"height": 250 | ||
} | ||
] | ||
}; | ||
|
||
beforeEach(() => { | ||
bidsRequestedOriginal = $$PREBID_GLOBAL$$._bidsRequested; | ||
addBidReponseStub = sandbox.stub(bidManager, 'addBidResponse'); | ||
$$PREBID_GLOBAL$$._bidsRequested.push(bidderRequest); | ||
}); | ||
|
||
afterEach(() => { | ||
sandbox.restore(); | ||
$$PREBID_GLOBAL$$._bidsRequested = bidsRequestedOriginal; | ||
}); | ||
|
||
it('should exist and be a function', () => { | ||
expect($$PREBID_GLOBAL$$.handleQuantcastCB).to.exist.and.to.be.a('function'); | ||
}); | ||
|
||
it('should not add bid when empty text response comes', () => { | ||
$$PREBID_GLOBAL$$.handleQuantcastCB(); | ||
sinon.assert.notCalled(addBidReponseStub); | ||
}); | ||
|
||
it('should not add bid when empty json response comes', () => { | ||
$$PREBID_GLOBAL$$.handleQuantcastCB(JSON.stringify({})); | ||
sinon.assert.notCalled(addBidReponseStub); | ||
}); | ||
|
||
it('should not add bid when malformed json response comes', () => { | ||
$$PREBID_GLOBAL$$.handleQuantcastCB('non json text'); | ||
sinon.assert.notCalled(addBidReponseStub); | ||
}); | ||
|
||
it('should add a bid object for each bid', () => { | ||
// You need the following call so that the in-memory storage of the bidRequest is carried out. Without this the callback won't work correctly. | ||
adapter.callBids(bidderRequest); | ||
$$PREBID_GLOBAL$$.handleQuantcastCB(JSON.stringify(bidderReponse)); | ||
sinon.assert.calledOnce(addBidReponseStub); | ||
expect(addBidReponseStub.firstCall.args[0]).to.eql("div-gpt-ad-1438287399331-0"); | ||
}); | ||
|
||
it('should return no bid even when requestId and sizes are missing', () =>{ | ||
let bidderReponse = { | ||
"bidderCode": "quantcast", | ||
"bids" : [ | ||
{ | ||
"statusCode" : 0, | ||
"placementCode" : bidderRequest.bids[0].bidId, | ||
} | ||
] | ||
}; | ||
|
||
// You need the following call so that the in-memory storage of the bidRequest is carried out. Without this the callback won't work correctly. | ||
adapter.callBids(bidderRequest); | ||
$$PREBID_GLOBAL$$.handleQuantcastCB(JSON.stringify(bidderReponse)); | ||
//sinon.assert.calledOnce(addBidReponseStub); | ||
//expect(addBidReponseStub.firstCall.args[0]).to.eql("div-gpt-ad-1438287399331-0"); | ||
}); | ||
}); | ||
|
||
}); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should really try to add a error bid here if possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mkendall07 I tried to, but at that point in code we don't have the placement code for which the empty text response came and hence returning an error bid isn't possible..