-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ad partner Bid Adapter: advertiser domains for Prebid 5 compliance (#…
…7347) * Add advertiserDomains field to adapter * Add working Unit ID * kick of Circle Ci tests * Change Unit ID * kick off CircleCi tests Co-authored-by: lovephp-sweety <sweety@dream.com> Co-authored-by: Chris Huie <phoenixtechnerd@gmail.com>
- Loading branch information
1 parent
4f76c4f
commit 61f4090
Showing
3 changed files
with
374 additions
and
1 deletion.
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 |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import {registerBidder} from '../src/adapters/bidderFactory.js'; | ||
import * as utils from '../src/utils.js' | ||
import {ajax} from '../src/ajax.js'; | ||
|
||
const BIDDER_CODE = 'adpartner'; | ||
export const ENDPOINT_PROTOCOL = 'https'; | ||
export const ENDPOINT_DOMAIN = 'a4p.adpartner.pro'; | ||
export const ENDPOINT_PATH = '/hb/bid'; | ||
|
||
export const spec = { | ||
code: BIDDER_CODE, | ||
|
||
isBidRequestValid: function (bidRequest) { | ||
return !!parseInt(bidRequest.params.unitId); | ||
}, | ||
|
||
buildRequests: function (validBidRequests, bidderRequest) { | ||
let referer = window.location.href; | ||
try { | ||
referer = typeof bidderRequest.refererInfo === 'undefined' | ||
? window.top.location.href | ||
: bidderRequest.refererInfo.referer; | ||
} catch (e) {} | ||
|
||
let bidRequests = []; | ||
let beaconParams = { | ||
tag: [], | ||
sizes: [], | ||
referer: '' | ||
}; | ||
|
||
validBidRequests.forEach(function(validBidRequest) { | ||
bidRequests.push({ | ||
unitId: parseInt(validBidRequest.params.unitId), | ||
adUnitCode: validBidRequest.adUnitCode, | ||
sizes: validBidRequest.sizes, | ||
bidId: validBidRequest.bidId, | ||
referer: referer | ||
}); | ||
|
||
beaconParams.tag.push(validBidRequest.params.unitId); | ||
beaconParams.sizes.push(spec.joinSizesToString(validBidRequest.sizes)); | ||
beaconParams.referer = encodeURIComponent(referer); | ||
}); | ||
|
||
beaconParams.tag = beaconParams.tag.join(','); | ||
beaconParams.sizes = beaconParams.sizes.join(','); | ||
|
||
let adPartnerRequestUrl = utils.buildUrl({ | ||
protocol: ENDPOINT_PROTOCOL, | ||
hostname: ENDPOINT_DOMAIN, | ||
pathname: ENDPOINT_PATH, | ||
search: beaconParams | ||
}); | ||
|
||
return { | ||
method: 'POST', | ||
url: adPartnerRequestUrl, | ||
data: JSON.stringify(bidRequests) | ||
}; | ||
}, | ||
|
||
joinSizesToString: function(sizes) { | ||
let res = []; | ||
sizes.forEach(function(size) { | ||
res.push(size.join('x')); | ||
}); | ||
|
||
return res.join('|'); | ||
}, | ||
|
||
interpretResponse: function (serverResponse, bidRequest) { | ||
const validBids = JSON.parse(bidRequest.data); | ||
|
||
if (typeof serverResponse.body === 'undefined') { | ||
return []; | ||
} | ||
|
||
return validBids | ||
.map(bid => ({ | ||
bid: bid, | ||
ad: serverResponse.body[bid.adUnitCode] | ||
})) | ||
.filter(item => item.ad) | ||
.map(item => spec.adResponse(item.bid, item.ad)); | ||
}, | ||
|
||
adResponse: function(bid, ad) { | ||
const bidObject = { | ||
requestId: bid.bidId, | ||
ad: ad.ad, | ||
cpm: ad.cpm, | ||
width: ad.width, | ||
height: ad.height, | ||
ttl: 60, | ||
creativeId: ad.creativeId, | ||
netRevenue: ad.netRevenue, | ||
currency: ad.currency, | ||
winNotification: ad.winNotification | ||
} | ||
|
||
bidObject.meta = {}; | ||
if (ad.adomain && ad.adomain.length > 0) { | ||
bidObject.meta.advertiserDomains = ad.adomain; | ||
} | ||
|
||
return bidObject; | ||
}, | ||
|
||
onBidWon: function(data) { | ||
data.winNotification.forEach(function(unitWon) { | ||
let adPartnerBidWonUrl = utils.buildUrl({ | ||
protocol: ENDPOINT_PROTOCOL, | ||
hostname: ENDPOINT_DOMAIN, | ||
pathname: unitWon.path | ||
}); | ||
|
||
if (unitWon.method === 'POST') { | ||
spec.postRequest(adPartnerBidWonUrl, JSON.stringify(unitWon.data)); | ||
} | ||
}); | ||
|
||
return true; | ||
}, | ||
|
||
postRequest(endpoint, data) { | ||
ajax(endpoint, null, data, {method: 'POST'}); | ||
} | ||
} | ||
|
||
registerBidder(spec); |
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 |
---|---|---|
|
@@ -23,7 +23,7 @@ About us : https://adpartner.pro | |
{ | ||
bidder: "adpartner", | ||
params: { | ||
unitId: 5809 | ||
unitId: 6698 | ||
} | ||
} | ||
] | ||
|
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,242 @@ | ||
import {expect} from 'chai'; | ||
import {spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH} from 'modules/adpartnerBidAdapter.js'; | ||
import {newBidder} from 'src/adapters/bidderFactory.js'; | ||
|
||
const BIDDER_CODE = 'adpartner'; | ||
|
||
describe('AdpartnerAdapter', function () { | ||
const adapter = newBidder(spec); | ||
|
||
describe('inherited functions', function () { | ||
it('exists and is a function', function () { | ||
expect(adapter.callBids).to.be.exist.and.to.be.a('function'); | ||
}); | ||
}); | ||
|
||
describe('isBidRequestValid', function () { | ||
it('should return true when required params found', function () { | ||
let validRequest = { | ||
'params': { | ||
'unitId': 123 | ||
} | ||
}; | ||
expect(spec.isBidRequestValid(validRequest)).to.equal(true); | ||
}); | ||
|
||
it('should return true when required params is srting', function () { | ||
let validRequest = { | ||
'params': { | ||
'unitId': '456' | ||
} | ||
}; | ||
expect(spec.isBidRequestValid(validRequest)).to.equal(true); | ||
}); | ||
|
||
it('should return false when required params are not passed', function () { | ||
let validRequest = { | ||
'params': { | ||
'unknownId': 123 | ||
} | ||
}; | ||
expect(spec.isBidRequestValid(validRequest)).to.equal(false); | ||
}); | ||
|
||
it('should return false when required params is 0', function () { | ||
let validRequest = { | ||
'params': { | ||
'unitId': 0 | ||
} | ||
}; | ||
expect(spec.isBidRequestValid(validRequest)).to.equal(false); | ||
}); | ||
}); | ||
|
||
describe('buildRequests', function () { | ||
let validEndpoint = ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + ENDPOINT_PATH + '?tag=123,456&sizes=300x250|300x600,728x90&referer=https%3A%2F%2Ftest.domain'; | ||
|
||
let validRequest = [ | ||
{ | ||
'bidder': BIDDER_CODE, | ||
'params': { | ||
'unitId': 123 | ||
}, | ||
'adUnitCode': 'adunit-code-1', | ||
'sizes': [[300, 250], [300, 600]], | ||
'bidId': '30b31c1838de1e' | ||
}, | ||
{ | ||
'bidder': BIDDER_CODE, | ||
'params': { | ||
'unitId': '456' | ||
}, | ||
'adUnitCode': 'adunit-code-2', | ||
'sizes': [[728, 90]], | ||
'bidId': '22aidtbx5eabd9' | ||
} | ||
]; | ||
|
||
let bidderRequest = { | ||
refererInfo: { | ||
referer: 'https://test.domain' | ||
} | ||
}; | ||
|
||
it('bidRequest HTTP method', function () { | ||
const request = spec.buildRequests(validRequest, bidderRequest); | ||
expect(request.method).to.equal('POST'); | ||
}); | ||
|
||
it('bidRequest url', function () { | ||
const request = spec.buildRequests(validRequest, bidderRequest); | ||
expect(request.url).to.equal(validEndpoint); | ||
}); | ||
|
||
it('bidRequest data', function () { | ||
const request = spec.buildRequests(validRequest, bidderRequest); | ||
const payload = JSON.parse(request.data); | ||
expect(payload[0].unitId).to.equal(123); | ||
expect(payload[0].sizes).to.deep.equal([[300, 250], [300, 600]]); | ||
expect(payload[0].bidId).to.equal('30b31c1838de1e'); | ||
expect(payload[1].unitId).to.equal(456); | ||
expect(payload[1].sizes).to.deep.equal([[728, 90]]); | ||
expect(payload[1].bidId).to.equal('22aidtbx5eabd9'); | ||
}); | ||
}); | ||
|
||
describe('joinSizesToString', function () { | ||
it('success convert sizes list to string', function () { | ||
const sizesStr = spec.joinSizesToString([[300, 250], [300, 600]]); | ||
expect(sizesStr).to.equal('300x250|300x600'); | ||
}); | ||
}); | ||
|
||
describe('interpretResponse', function () { | ||
const bidRequest = { | ||
'method': 'POST', | ||
'url': ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + ENDPOINT_PATH + '?tag=123,456&code=adunit-code-1,adunit-code-2&bid=30b31c1838de1e,22aidtbx5eabd9&sizes=300x250|300x600,728x90&referer=https%3A%2F%2Ftest.domain', | ||
'data': '[{"unitId": 13144370,"adUnitCode": "div-gpt-ad-1460505748561-0","sizes": [[300, 250], [300, 600]],"bidId": "2bdcb0b203c17d","referer": "https://test.domain/index.html"},{"unitId": 13144370,"adUnitCode":"div-gpt-ad-1460505748561-1","sizes": [[768, 90]],"bidId": "3dc6b8084f91a8","referer": "https://test.domain/index.html"}]' | ||
}; | ||
|
||
const bidResponse = { | ||
body: { | ||
'div-gpt-ad-1460505748561-0': | ||
{ | ||
'ad': '<div>ad</div>', | ||
'width': 300, | ||
'height': 250, | ||
'creativeId': '8:123456', | ||
'adomain': [ | ||
'test.domain' | ||
], | ||
'syncs': [ | ||
{'type': 'image', 'url': 'https://test.domain/tracker_1.gif'}, | ||
{'type': 'image', 'url': 'https://test.domain/tracker_2.gif'}, | ||
{'type': 'image', 'url': 'https://test.domain/tracker_3.gif'} | ||
], | ||
'winNotification': [ | ||
{ | ||
'method': 'POST', | ||
'path': '/hb/bid_won?test=1', | ||
'data': { | ||
'ad': [ | ||
{'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'} | ||
], | ||
'unit_id': 1234, | ||
'site_id': 123 | ||
} | ||
} | ||
], | ||
'cpm': 0.01, | ||
'currency': 'USD', | ||
'netRevenue': true | ||
} | ||
}, | ||
headers: {} | ||
}; | ||
|
||
it('result is correct', function () { | ||
const result = spec.interpretResponse(bidResponse, bidRequest); | ||
expect(result[0].requestId).to.equal('2bdcb0b203c17d'); | ||
expect(result[0].cpm).to.equal(0.01); | ||
expect(result[0].width).to.equal(300); | ||
expect(result[0].height).to.equal(250); | ||
expect(result[0].creativeId).to.equal('8:123456'); | ||
expect(result[0].currency).to.equal('USD'); | ||
expect(result[0].ttl).to.equal(60); | ||
expect(result[0].meta.advertiserDomains).to.deep.equal(['test.domain']); | ||
expect(result[0].winNotification[0]).to.deep.equal({'method': 'POST', 'path': '/hb/bid_won?test=1', 'data': {'ad': [{'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'}], 'unit_id': 1234, 'site_id': 123}}); | ||
}); | ||
}); | ||
|
||
describe('adResponse', function () { | ||
const bid = { | ||
'unitId': 13144370, | ||
'adUnitCode': 'div-gpt-ad-1460505748561-0', | ||
'sizes': [[300, 250], [300, 600]], | ||
'bidId': '2bdcb0b203c17d', | ||
'referer': 'https://test.domain/index.html' | ||
}; | ||
const ad = { | ||
'ad': '<div>ad</div>', | ||
'width': 300, | ||
'height': 250, | ||
'creativeId': '8:123456', | ||
'syncs': [], | ||
'winNotification': [], | ||
'cpm': 0.01, | ||
'currency': 'USD', | ||
'netRevenue': true, | ||
'adomain': [ | ||
'test.domain' | ||
], | ||
}; | ||
|
||
it('fill ad for response', function () { | ||
const result = spec.adResponse(bid, ad); | ||
expect(result.requestId).to.equal('2bdcb0b203c17d'); | ||
expect(result.cpm).to.equal(0.01); | ||
expect(result.width).to.equal(300); | ||
expect(result.height).to.equal(250); | ||
expect(result.creativeId).to.equal('8:123456'); | ||
expect(result.currency).to.equal('USD'); | ||
expect(result.ttl).to.equal(60); | ||
expect(result.meta.advertiserDomains).to.deep.equal(['test.domain']); | ||
}); | ||
}); | ||
|
||
describe('onBidWon', function () { | ||
const bid = { | ||
winNotification: [ | ||
{ | ||
'method': 'POST', | ||
'path': '/hb/bid_won?test=1', | ||
'data': { | ||
'ad': [ | ||
{'dsp': 8, 'id': 800008, 'cost': 0.01, 'nurl': 'http://test.domain/'} | ||
], | ||
'unit_id': 1234, | ||
'site_id': 123 | ||
} | ||
} | ||
] | ||
}; | ||
|
||
let ajaxStub; | ||
|
||
beforeEach(() => { | ||
ajaxStub = sinon.stub(spec, 'postRequest') | ||
}) | ||
|
||
afterEach(() => { | ||
ajaxStub.restore() | ||
}) | ||
|
||
it('calls adpartner\'s callback endpoint', () => { | ||
const result = spec.onBidWon(bid); | ||
expect(result).to.equal(true); | ||
expect(ajaxStub.calledOnce).to.equal(true); | ||
expect(ajaxStub.firstCall.args[0]).to.equal(ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + '/hb/bid_won?test=1'); | ||
expect(ajaxStub.firstCall.args[1]).to.deep.equal(JSON.stringify(bid.winNotification[0].data)); | ||
}); | ||
}); | ||
}); |