Skip to content

Commit

Permalink
Trafficroots Bid Adapter Submission (#2993)
Browse files Browse the repository at this point in the history
* Trafficroots bid adapter submission.  Thank you!

* unit test

* typo fix
  • Loading branch information
cary67 authored and idettman committed Sep 25, 2018
1 parent 005df8b commit 726d0a4
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 0 deletions.
129 changes: 129 additions & 0 deletions modules/trafficrootsBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import {registerBidder} from 'src/adapters/bidderFactory';
import * as utils from 'src/utils';

const TR_BIDDER_CODE = 'trafficroots';
const TR_CURRENCY = 'USD';
const TR_DEFAULT_BID_URL = '//service.trafficroots.com/prebid';
const TR_TTL = 60;

const LOCATION_PARAM_NAME = 'siteurl';
const ID_PARAM_NAME = 'id';
const IFRAME_PARAM_NAME = 'if';
const ZONE_ID_PARAM_NAME = 'zoneId';
const SIZE_PARAM_NAME = 'size';
const KEYWORDS_PARAM_NAME = 'keywords';
const MOBILE_PARAM_NAME = 'mobile';
const TRID_PARAM_NAME = 'trid';

const ARRAY_PARAM_SEPARATOR = ';';
const ARRAY_SIZE_SEPARATOR = ',';
const SIZE_SEPARATOR = 'x';
const IS_MOBILE = window.navigator.userAgent.toLowerCase().includes('mobi');

let keywords = () => {
let clean = input => {
return input.replace(/\W/g, ' ').replace(/[ ]{2,}/g, ' ').trim();
};
let meta = name => {
let tag = document.querySelector("meta[name='" + name + "']");
return (tag !== null) ? tag.getAttribute('content') : '';
};
return encodeURIComponent(
clean(
meta('keywords') + ' ' + meta('description') + ' ' + document.title
)
).substring(0, 400);
};

export const spec = {
code: TR_BIDDER_CODE,
isBidRequestValid: function(bid) {
return bid.params && !!bid.params.zoneId;
},

buildRequests: function(validBidRequests, bidderRequest) {
let deliveryUrl = '';
const idParams = [];
const sizeParams = [];
const zoneIds = [];
let trid = '';
if (window.localStorage) {
try {
var myid = window.localStorage.getItem('trafficroots:trid');
if (myid) {
trid = myid;
}
} catch (ex) {
}
}
utils._each(validBidRequests, function(bid) {
if (!deliveryUrl && typeof bid.params.deliveryUrl === 'string') {
deliveryUrl = bid.params.deliveryUrl;
}
idParams.push(bid.bidId);
sizeParams.push(bid.sizes.map(size => size.join(SIZE_SEPARATOR)).join(ARRAY_SIZE_SEPARATOR));
zoneIds.push(bid.params.zoneId);
});

if (!deliveryUrl) {
deliveryUrl = TR_DEFAULT_BID_URL;
}

let data = {
[IFRAME_PARAM_NAME]: 0,
[LOCATION_PARAM_NAME]: utils.getTopWindowUrl(),
[SIZE_PARAM_NAME]: sizeParams.join(ARRAY_PARAM_SEPARATOR),
[ID_PARAM_NAME]: idParams.join(ARRAY_PARAM_SEPARATOR),
[ZONE_ID_PARAM_NAME]: zoneIds.join(ARRAY_PARAM_SEPARATOR),
[MOBILE_PARAM_NAME]: IS_MOBILE,
[KEYWORDS_PARAM_NAME]: decodeURIComponent(keywords()),
[TRID_PARAM_NAME]: trid
};

if (bidderRequest && bidderRequest.gdprConsent) {
data.gdpr = {
applies: bidderRequest.gdprConsent.gdprApplies,
consent: bidderRequest.gdprConsent.consentString
};
}

return {
method: 'GET',
url: deliveryUrl,
data: data
};
},

interpretResponse: function(serverResponses, request) {
const bidResponses = [];
var tridSet = false;
utils._each(serverResponses.body, function(response) {
if (!tridSet) {
try {
if (window.localStorage) {
window.localStorage.setItem('trafficroots:trid', response.trid);
tridSet = true;
}
} catch (ex) {}
}
if (response.cpm > 0) {
const bidResponse = {
requestId: response.id,
creativeId: response.id,
adId: response.id,
cpm: response.cpm,
width: response.width,
height: response.height,
currency: TR_CURRENCY,
netRevenue: true,
ttl: TR_TTL,
ad: response.ad
};
bidResponses.push(bidResponse);
}
});
return bidResponses;
}
};

registerBidder(spec);
37 changes: 37 additions & 0 deletions modules/trafficrootsBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Overview

Module Name: Trafficroots Bid Adapter

Module Type: Bidder Adapter

Maintainer: cary@trafficroots.com

# Description

Module that connects to Trafficroots demand sources

# Test Parameters
```javascript

var adUnits = [
{
code: 'test-div',
sizes: [[300, 250],[300,600]], // a display size
bids: [
{
bidder: 'trafficroots',
params: {
zoneId: 'aa0444af31',
deliveryUrl: location.protocol + '//service.trafficroots.com/prebid'
}
},{
bidder: 'trafficroots',
params: {
zoneId: '8f527a4835',
deliveryUrl: location.protocol + '//service.trafficroots.com/prebid'
}
}
]
}
];
```
149 changes: 149 additions & 0 deletions test/spec/modules/trafficrootsBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { expect } from 'chai';
import { spec } from 'modules/trafficrootsBidAdapter';

describe('trafficrootsAdapterTests', () => {
describe('bidRequestValidity', () => {
it('bidRequest with zoneId and deliveryUrl params', () => {
expect(spec.isBidRequestValid({
bidder: 'trafficroots',
params: {
zoneId: 'aa0444af31',
deliveryUrl: 'https://service.trafficroosts.com/prebid'
}
})).to.equal(true);
});

it('bidRequest with only zoneId', () => {
expect(spec.isBidRequestValid({
bidder: 'trafficroots',
params: {
zoneId: '8f527a4835'
}
})).to.equal(true);
});

it('bidRequest with only deliveryUrl', () => {
expect(spec.isBidRequestValid({
bidder: 'trafficroots',
params: {
deliveryUrl: 'https://service.trafficroosts.com/prebid'
}
})).to.equal(false);
});
});

describe('bidRequest', () => {
const bidRequests = [{
'bidder': 'trafficroots',
'bidId': '29fa5c08928bde',
'params': {
'zoneId': 'aa0444af31',
},
'adUnitCode': 'div-gpt-ad-1460505748561-0',
'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec',
'sizes': [[300, 250], [300, 600]],
'bidderRequestId': '418b37f85e772c',
'auctionId': '18fd8b8b0bd757'
}, {
'bidder': 'trafficroots',
'bidId': '29fa5c08928bde',
'params': {
'zoneId': '8f527a4835',
'deliveryUrl': 'https://service.trafficroosts.com/prebid'
},
'adUnitCode': 'div-gpt-ad-1460505748561-0',
'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec',
'sizes': [[300, 250], [300, 600]],
'bidderRequestId': '418b37f85e772c',
'auctionId': '18fd8b8b0bd757'
}];

it('bidRequest method', () => {
const request = spec.buildRequests(bidRequests);
expect(request.method).to.equal('GET');
});

it('bidRequest url', () => {
const request = spec.buildRequests(bidRequests);
expect(request.url).to.match(new RegExp(`${bidRequests[1].params.deliveryUrl}`));
});

it('bidRequest data', () => {
const request = spec.buildRequests(bidRequests);
expect(request.data).to.exists;
});

it('bidRequest zoneIds', () => {
const request = spec.buildRequests(bidRequests);
expect(request.data.zoneId).to.equal('aa0444af31;8f527a4835');
});

it('bidRequest gdpr consent', () => {
const consentString = 'consentString';
const bidderRequest = {
bidderCode: 'trafficroots',
auctionId: '18fd8b8b0bd757',
bidderRequestId: '418b37f85e772c',
timeout: 3000,
gdprConsent: {
consentString: consentString,
gdprApplies: true
}
};

const request = spec.buildRequests(bidRequests, bidderRequest);

expect(request.data.gdpr).to.exist;
expect(request.data.gdpr.applies).to.exist.and.to.be.true;
expect(request.data.gdpr.consent).to.exist.and.to.equal(consentString);
});
});

describe('interpretResponse', () => {
const bidRequest = [{
'bidder': 'trafficroots',
'bidId': '29fa5c08928bde',
'params': {
'zoneId': 'aa0444af31',
},
'adUnitCode': 'div-gpt-ad-1460505748561-0',
'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec',
'sizes': [[300, 250], [300, 600]],
'bidderRequestId': '418b37f85e772c',
'auctionId': '18fd8b8b0bd757'
}];

const bidResponse = {
body: [{
'id': 'div-gpt-ad-1460505748561-0',
'ad': 'test ad',
'width': 320,
'height': 250,
'cpm': 5.2
}],
headers: {}
};

it('required keys', () => {
const result = spec.interpretResponse(bidResponse, bidRequest);

let requiredKeys = [
'requestId',
'creativeId',
'adId',
'cpm',
'width',
'height',
'currency',
'netRevenue',
'ttl',
'ad'
];

let resultKeys = Object.keys(result[0]);
resultKeys.forEach(function(key) {
expect(requiredKeys.indexOf(key) !== -1).to.equal(true);
});
})
});
});

0 comments on commit 726d0a4

Please sign in to comment.