-
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.
* add tim adapter * add tim spec file * add tim md file * added tests. change adapter. * dummy commit for re-running tests * new code for prebid2.0 * change alias name * change domain name
- Loading branch information
1 parent
e93d17d
commit 0be3422
Showing
3 changed files
with
355 additions
and
0 deletions.
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,177 @@ | ||
import * as utils from 'src/utils'; | ||
import {registerBidder} from 'src/adapters/bidderFactory'; | ||
import * as bidfactory from '../src/bidfactory'; | ||
var CONSTANTS = require('src/constants.json'); | ||
const BIDDER_CODE = 'tim'; | ||
|
||
function parseBidRequest(bidRequest) { | ||
let params = bidRequest.url.split('?')[1]; | ||
var obj = {}; | ||
var pairs = params.split('&'); | ||
try { | ||
for (var i in pairs) { | ||
var split = pairs[i].split('='); | ||
obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]); | ||
} | ||
} catch (e) { | ||
utils.logError(e); | ||
} | ||
|
||
return JSON.parse(obj.br); | ||
} | ||
|
||
function formatAdMarkup(bid) { | ||
var adm = bid.adm; | ||
if ('nurl' in bid) { | ||
adm += createTrackPixelHtml(bid.nurl); | ||
} | ||
return `<!DOCTYPE html><html><head><title></title><body style='margin:0px;padding:0px;'>${adm}</body></head>`; | ||
} | ||
|
||
function createTrackPixelHtml(url) { | ||
if (!url) { | ||
return ''; | ||
} | ||
let img = '<div style="position:absolute;left:0px;top:0px;visibility:hidden;">'; | ||
img += '<img src="' + url + '"></div>'; | ||
return img; | ||
} | ||
|
||
export const spec = { | ||
code: BIDDER_CODE, | ||
aliases: ['timmedia'], | ||
|
||
isBidRequestValid: function(bid) { | ||
if (bid.params && bid.params.publisherid && bid.params.placementCode) { | ||
return true; | ||
} if (!bid.params) { | ||
utils.logError('bid not valid: params were not provided'); | ||
} else if (!bid.params.publisherid) { | ||
utils.logError('bid not valid: publisherid was not provided'); | ||
} else if (!bid.params.placementCode) { | ||
utils.logError('bid not valid: placementCode was not provided'); | ||
} return false; | ||
}, | ||
|
||
buildRequests: function(validBidRequests, bidderRequest) { | ||
var requests = []; | ||
for (var i = 0; i < validBidRequests.length; i++) { | ||
requests.push(this.createRTBRequestURL(validBidRequests[i])); | ||
} | ||
return requests; | ||
}, | ||
|
||
createRTBRequestURL: function(bidReq) { | ||
// build bid request object | ||
var domain = window.location.host; | ||
var page = window.location.href; | ||
var publisherid = bidReq.params.publisherid; | ||
var bidFloor = bidReq.params.bidfloor; | ||
var placementCode = bidReq.params.placementCode; | ||
|
||
var adW = bidReq.mediaTypes.banner.sizes[0][0]; | ||
var adH = bidReq.mediaTypes.banner.sizes[0][1]; | ||
|
||
// build bid request with impressions | ||
var bidRequest = { | ||
id: utils.getUniqueIdentifierStr(), | ||
imp: [{ | ||
id: bidReq.bidId, | ||
banner: { | ||
w: adW, | ||
h: adH | ||
}, | ||
tagid: placementCode, | ||
bidfloor: bidFloor | ||
}], | ||
site: { | ||
domain: domain, | ||
page: page, | ||
publisher: { | ||
id: publisherid | ||
} | ||
}, | ||
device: { | ||
'language': this.getLanguage(), | ||
'w': adW, | ||
'h': adH, | ||
'js': 1, | ||
'ua': navigator.userAgent | ||
} | ||
}; | ||
if (!bidFloor) { | ||
delete bidRequest.imp['bidfloor']; | ||
} | ||
|
||
bidRequest.bidId = bidReq.bidId; | ||
var url = '//hb.timmedia-hb.com/api/v2/services/prebid/' + publisherid + '/' + placementCode + '?' + 'br=' + encodeURIComponent(JSON.stringify(bidRequest)); | ||
return { | ||
method: 'GET', | ||
url: url, | ||
data: '', | ||
options: {withCredentials: false} | ||
}; | ||
}, | ||
|
||
interpretResponse: function(serverResponse, bidRequest) { | ||
bidRequest = parseBidRequest(bidRequest); | ||
var bidResp = serverResponse.body; | ||
const bidResponses = []; | ||
if ((!bidResp || !bidResp.id) || | ||
(!bidResp.seatbid || bidResp.seatbid.length === 0 || !bidResp.seatbid[0].bid || bidResp.seatbid[0].bid.length === 0)) { | ||
return []; | ||
} | ||
bidResp.seatbid[0].bid.forEach(function (bidderBid) { | ||
var responseCPM; | ||
var placementCode = ''; | ||
if (bidRequest) { | ||
var bidResponse = bidfactory.createBid(1); | ||
placementCode = bidRequest.placementCode; | ||
bidRequest.status = CONSTANTS.STATUS.GOOD; | ||
responseCPM = parseFloat(bidderBid.price); | ||
if (responseCPM === 0) { | ||
var bid = bidfactory.createBid(2); | ||
bid.bidderCode = BIDDER_CODE; | ||
bidResponses.push(bid); | ||
return bidResponses; | ||
} | ||
bidResponse.placementCode = placementCode; | ||
bidResponse.size = bidRequest.sizes; | ||
bidResponse.creativeId = bidderBid.id; | ||
bidResponse.bidderCode = BIDDER_CODE; | ||
bidResponse.cpm = responseCPM; | ||
bidResponse.ad = formatAdMarkup(bidderBid); | ||
bidResponse.width = parseInt(bidderBid.w); | ||
bidResponse.height = parseInt(bidderBid.h); | ||
bidResponse.currency = bidResp.cur; | ||
bidResponse.netRevenue = true; | ||
bidResponse.requestId = bidRequest.bidId; | ||
bidResponse.ttl = 180; | ||
bidResponses.push(bidResponse); | ||
} | ||
}); | ||
return bidResponses; | ||
}, | ||
getLanguage: function() { | ||
const language = navigator.language ? 'language' : 'userLanguage'; | ||
return navigator[language].split('-')[0]; | ||
}, | ||
|
||
getUserSyncs: function(syncOptions, serverResponses) { | ||
const syncs = [] | ||
return syncs; | ||
}, | ||
|
||
onTimeout: function(data) { | ||
// Bidder specifc code | ||
}, | ||
|
||
onBidWon: function(bid) { | ||
// Bidder specific code | ||
}, | ||
|
||
onSetTargeting: function(bid) { | ||
// Bidder specific code | ||
}, | ||
} | ||
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 |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Overview | ||
|
||
``` | ||
Module Name: tim Bidder Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: boris@thetimmedia.com | ||
``` | ||
|
||
# Description | ||
|
||
Module that connects to tim's demand sources | ||
|
||
# Test Parameters | ||
``` | ||
var adUnits = [{ | ||
"code":"99", | ||
"sizes":[[300,250]], | ||
"bids":[{"bidder":"tim", | ||
"params":{ | ||
"placementCode":"testPlacementCode", | ||
"publisherid":"testpublisherid" | ||
} | ||
}] | ||
}] | ||
``` | ||
|
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,152 @@ | ||
import { expect } from 'chai'; | ||
import { spec } from 'modules/timBidAdapter'; | ||
|
||
describe('timAdapterTests', function () { | ||
describe('bidRequestValidity', function () { | ||
it('bidRequest with publisherid and placementCode params', function () { | ||
expect(spec.isBidRequestValid({ | ||
bidder: 'tim', | ||
params: { | ||
publisherid: 'testid', | ||
placementCode: 'testplacement' | ||
} | ||
})).to.equal(true); | ||
}); | ||
|
||
it('bidRequest with only publisherid', function () { | ||
expect(spec.isBidRequestValid({ | ||
bidder: 'tim', | ||
params: { | ||
publisherid: 'testid' | ||
} | ||
})).to.equal(false); | ||
}); | ||
|
||
it('bidRequest with only placementCode', function () { | ||
expect(spec.isBidRequestValid({ | ||
bidder: 'tim', | ||
params: { | ||
placementCode: 'testplacement' | ||
} | ||
})).to.equal(false); | ||
}); | ||
|
||
it('bidRequest without params', function () { | ||
expect(spec.isBidRequestValid({ | ||
bidder: 'tim', | ||
})).to.equal(false); | ||
}); | ||
}); | ||
|
||
describe('buildRequests', function () { | ||
const validBidRequests = [{ | ||
'bidder': 'tim', | ||
'params': {'placementCode': 'placementCode', 'publisherid': 'testpublisherid'}, | ||
'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, | ||
'adUnitCode': 'adUnitCode', | ||
'transactionId': 'transactionId', | ||
'sizes': [[300, 250]], | ||
'bidId': 'bidId', | ||
'bidderRequestId': 'bidderRequestId', | ||
'auctionId': 'auctionId', | ||
'src': 'client', | ||
'bidRequestsCount': 1 | ||
}]; | ||
|
||
it('bidRequest method', function () { | ||
const requests = spec.buildRequests(validBidRequests); | ||
expect(requests[0].method).to.equal('GET'); | ||
}); | ||
|
||
it('bidRequest url', function () { | ||
const requests = spec.buildRequests(validBidRequests); | ||
expect(requests[0].url).to.exist; | ||
}); | ||
|
||
it('bidRequest data', function () { | ||
const requests = spec.buildRequests(validBidRequests); | ||
expect(requests[0].data).to.exist; | ||
}); | ||
|
||
it('bidRequest options', function () { | ||
const requests = spec.buildRequests(validBidRequests); | ||
expect(requests[0].options).to.exist; | ||
}); | ||
}); | ||
|
||
describe('interpretResponse', function () { | ||
const bidRequest = { | ||
'method': 'GET', | ||
'url': '//bidder.url/api/prebid/testpublisherid/header-bid-tag-0?br=%7B%22id%22%3A%223a3ac0d7fc2548%22%2C%22imp%22%3A%5B%7B%22id%22%3A%22251b8a6d3aac3e%22%2C%22banner%22%3A%7B%22w%22%3A300%2C%22h%22%3A250%7D%2C%22tagid%22%3A%22header-bid-tag-0%22%7D%5D%2C%22site%22%3A%7B%22domain%22%3A%22www.chinatimes.com%22%2C%22page%22%3A%22http%3A%2F%2Fwww.chinatimes.com%2Fa%22%2C%22publisher%22%3A%7B%22id%22%3A%22testpublisherid%22%7D%7D%2C%22device%22%3A%7B%22language%22%3A%22en%22%2C%22w%22%3A300%2C%22h%22%3A250%2C%22js%22%3A1%2C%22ua%22%3A%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F71.0.3578.98%20Safari%2F537.36%22%7D%2C%22bidId%22%3A%22251b8a6d3aac3e%22%7D', | ||
'data': '', | ||
'options': {'withCredentials': false} | ||
}; | ||
|
||
const serverResponse = { | ||
'body': { | ||
'id': 'id', | ||
'seatbid': [] | ||
}, | ||
'headers': {} | ||
}; | ||
|
||
it('check empty array response', function () { | ||
const result = spec.interpretResponse(serverResponse, bidRequest); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
|
||
const validBidRequest = { | ||
'method': 'GET', | ||
'url': '//bidder.url/api/v2/services/prebid/testpublisherid/placementCodeTest?br=%7B%22id%22%3A%2248640869bd9db94%22%2C%22imp%22%3A%5B%7B%22id%22%3A%224746fcaa11197f3%22%2C%22banner%22%3A%7B%22w%22%3A300%2C%22h%22%3A250%7D%2C%22tagid%22%3A%22placementCodeTest%22%7D%5D%2C%22site%22%3A%7B%22domain%22%3A%22mediamart.tv%22%2C%22page%22%3A%22http%3A%2F%2Fmediamart.tv%2Fsas%2Ftests%2FDesktop%2Fcaesar%2Fdfptest.html%22%2C%22publisher%22%3A%7B%22id%22%3A%22testpublisherid%22%7D%7D%2C%22device%22%3A%7B%22language%22%3A%22en%22%2C%22w%22%3A300%2C%22h%22%3A250%2C%22js%22%3A1%2C%22ua%22%3A%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F71.0.3578.98%20Safari%2F537.36%22%7D%2C%22bidId%22%3A%224746fcaa11197f3%22%7D', | ||
'data': '', | ||
'options': {'withCredentials': false} | ||
}; | ||
const validServerResponse = { | ||
'body': {'id': 'id', | ||
'seatbid': [ | ||
{'bid': [{'id': 'id', | ||
'impid': 'impid', | ||
'price': 3, | ||
'nurl': 'https://bidder.url/api/v1/?price=${AUCTION_PRICE}&bidcur=USD&bidid=bidid=true', | ||
'adm': '<script type=\"text/javascript\" src=\"https://domain.com/Player.php"></script>', | ||
'adomain': [''], | ||
'cid': '1', | ||
'crid': '700', | ||
'w': 300, | ||
'h': 250 | ||
}]}], | ||
'bidid': 'bidid', | ||
'cur': 'USD' | ||
}, | ||
'headers': {} | ||
}; | ||
it('required keys', function () { | ||
const result = spec.interpretResponse(validServerResponse, validBidRequest); | ||
|
||
let requiredKeys = [ | ||
'requestId', | ||
'creativeId', | ||
'adId', | ||
'cpm', | ||
'width', | ||
'height', | ||
'currency', | ||
'netRevenue', | ||
'ttl', | ||
'ad' | ||
]; | ||
|
||
let resultKeys = Object.keys(result[0]); | ||
requiredKeys.forEach(function(key) { | ||
expect(resultKeys.indexOf(key) !== -1).to.equal(true); | ||
}); | ||
}) | ||
}); | ||
|
||
describe('getUserSyncs', function () { | ||
it('check empty response getUserSyncs', function () { | ||
const result = spec.getUserSyncs('', ''); | ||
expect(result).to.deep.equal([]); | ||
}); | ||
}); | ||
}); |