Skip to content

Commit

Permalink
modules: Implement SmartRTB adapter and spec. (#3575)
Browse files Browse the repository at this point in the history
* modules: Implement SmartRTB adapter and spec.

* Fix for-loop syntax to support IE; refactor getDomain out of exported set.
  • Loading branch information
evanmsmrtb authored and jsnellbaker committed Mar 19, 2019
1 parent 90cefb8 commit c0fdf02
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 0 deletions.
111 changes: 111 additions & 0 deletions modules/smartrtbBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import * as utils from 'src/utils';
import {registerBidder} from 'src/adapters/bidderFactory';
const BIDDER_CODE = 'smartrtb';

function getDomain () {
if (!utils.inIframe()) {
return window.location.hostname
}
let origins = window.document.location.ancestorOrigins
if (origins && origins.length > 0) {
return origins[origins.length - 1]
}
}

export const spec = {
code: BIDDER_CODE,
aliases: ['smrtb'],
isBidRequestValid: function(bid) {
return (bid.params.pubId !== null &&
bid.params.medId !== null &&
bid.params.zoneId !== null);
},
buildRequests: function(validBidRequests, bidderRequest) {
let stack = (bidderRequest.refererInfo &&
bidderRequest.refererInfo.stack ? bidderRequest.refererInfo
: [])

const payload = {
start_time: utils.timestamp(),
tmax: 120,
language: window.navigator.userLanguage || window.navigator.language,
site: {
domain: getDomain(),
iframe: !bidderRequest.refererInfo.reachedTop,
url: stack && stack.length > 0 ? [stack.length - 1] : null,
https: (window.location.protocol === 'https:'),
referrer: bidderRequest.refererInfo.referer
},
imps: []
};

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

for (let x = 0; x < validBidRequests.length; x++) {
let req = validBidRequests[x]

payload.imps.push({
pub_id: req.params.pubId,
med_id: req.params.medId,
zone_id: req.params.zoneId,
bid_id: req.bidId,
imp_id: req.transactionId,
sizes: req.sizes,
force_bid: req.params.forceBid
});
}

return {
method: 'POST',
url: '//pubs.smrtb.com/json/publisher/prebid',
data: JSON.stringify(payload)
};
},
interpretResponse: function(serverResponse, bidRequest) {
const bidResponses = [];
let res = serverResponse.body;
if (!res.bids || !res.bids.length) {
return []
}

for (let x = 0; x < serverResponse.body.bids.length; x++) {
let bid = serverResponse.body.bids[x]

bidResponses.push({
requestId: bid.bid_id,
cpm: bid.cpm,
width: bid.w,
height: bid.h,
ad: bid.html,
ttl: 120,
creativeId: bid.crid,
netRevenue: true,
currency: 'USD'
})
}

return bidResponses;
},
getUserSyncs: function(syncOptions, serverResponses) {
const syncs = []
if (syncOptions.iframeEnabled) {
syncs.push({
type: 'iframe',
url: '//ads.smrtb.com/sync'
});
} else if (syncOptions.pixelEnabled) {
syncs.push({
type: 'image',
url: '//ads.smrtb.com/sync'
});
}
return syncs;
}
};

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

```
Module Name: Smart RTB (smrtb.com) Bidder Adapter
Module Type: Bidder Adapter
Maintainer: evanm@smrtb.com
```

# Description

Prebid adapter for Smart RTB. Requires approval and account setup.

# Test Parameters

## Web
```
var adUnits = [
{
code: 'test-div',
sizes: [[300, 250]],
bids: [
{
bidder: "smartrtb",
params: {
pubId: 123,
medId: "m_00a95d003340dbb2fcb8ee668a84fa",
zoneId: "z_261b6c7e7d4d4985393b293cc903d1",
force_bid: true
}
}
]
}
];
```
109 changes: 109 additions & 0 deletions test/spec/modules/smartrtbBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { expect } from 'chai'
import { spec, _getPlatform } from 'modules/smartrtbBidAdapter'
import { newBidder } from 'src/adapters/bidderFactory'

describe('SmartRTBBidAdapter', function () {
const adapter = newBidder(spec)

let bidRequest = {
bidId: '123',
transactionId: '456',
sizes: [[ 300, 250 ]],
params: {
pubId: 123,
medId: 'm_00a95d003340dbb2fcb8ee668a84fa',
zoneId: 'z_261b6c7e7d4d4985393b293cc903d1'
}
}

describe('codes', function () {
it('should return a bidder code of smartrtb', function () {
expect(spec.code).to.equal('smartrtb')
})
it('should alias smrtb', function () {
expect(spec.aliases.length > 0 && spec.aliases[0] === 'smrtb').to.be.true
})
})

describe('isBidRequestValid', function () {
it('should return true if all params present', function () {
expect(spec.isBidRequestValid(bidRequest)).to.be.true
})

it('should return false if any parameter missing', function () {
expect(spec.isBidRequestValid(Object.assign(bidRequest, { params: { pubId: null } }))).to.be.false
expect(spec.isBidRequestValid(Object.assign(bidRequest, { params: { medId: null } }))).to.be.false
expect(spec.isBidRequestValid(Object.assign(bidRequest, { params: { zoneId: null } }))).to.be.false
})
})

describe('buildRequests', function () {
let req = spec.buildRequests([ bidRequest ], { refererInfo: { } })
let rdata

it('should return request object', function () {
expect(req).to.not.be.null
})

it('should build request data', function () {
expect(req.data).to.not.be.null
})

it('should include one request', function () {
rdata = JSON.parse(req.data)
expect(rdata.imps.length).to.equal(1)
})

it('should include all publisher params', function () {
let r = rdata.imps[0]
expect(r.pub_id !== null && r.med_id !== null && r.zone_id !== null).to.be.true
})
})

describe('interpretResponse', function () {
it('should form compliant bid object response', function () {
let res = {
body: {
bids: [{
bid_id: '123',
cpm: 1.23,
w: 300,
h: 250,
html: '<b>deadbeef</b>',
crid: 'crid'
}]
}
}

let ir = spec.interpretResponse(res, bidRequest)

expect(ir.length).to.equal(1)

let en = ir[0]

expect(en.requestId != null &&
en.cpm != null && typeof en.cpm === 'number' &&
en.width != null && typeof en.width === 'number' &&
en.height != null && typeof en.height === 'number' &&
en.ad != null &&
en.creativeId != null
).to.be.true
})
})

describe('getUserSyncs', function () {
it('should return iframe sync', function () {
let sync = spec.getUserSyncs({ iframeEnabled: true })
expect(sync.length).to.equal(1)
expect(sync[0].type === 'iframe')
expect(typeof sync[0].url === 'string')
})

it('should return pixel sync', function () {
let sync = spec.getUserSyncs({ pixelEnabled: true })
expect(sync.length).to.equal(1)
expect(sync[0].type === 'image')
expect(typeof sync[0].url === 'string')
})
})
})

0 comments on commit c0fdf02

Please sign in to comment.