Skip to content
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

Sovrn Bid Adapter: added FPD support #6639

Merged
merged 3 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions modules/sovrnBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as utils from '../src/utils.js'
import { registerBidder } from '../src/adapters/bidderFactory.js'
import { BANNER } from '../src/mediaTypes.js'
import { createEidsArray } from './userId/eids.js';
import {config} from '../src/config.js';

export const spec = {
code: 'sovrn',
Expand Down Expand Up @@ -72,30 +73,29 @@ export const spec = {
bidfloor: floorInfo.floor
}

const segmentsString = utils.getBidIdParameter('segments', bid.params)
imp.ext = utils.getBidIdParameter('ext', bid.ortb2Imp) || undefined

const segmentsString = utils.getBidIdParameter('segments', bid.params)
if (segmentsString) {
imp.ext = {
deals: segmentsString.split(',').map(deal => deal.trim())
}
imp.ext = imp.ext || {}
imp.ext.deals = segmentsString.split(',').map(deal => deal.trim())
}
sovrnImps.push(imp)
})

sovrnImps.push(imp);
});

const page = bidderRequest.refererInfo.referer
const fpd = config.getConfig('ortb2') || {}

const site = fpd.site || {}
site.page = bidderRequest.refererInfo.referer
// clever trick to get the domain
const domain = utils.parseUrl(page).hostname
site.domain = utils.parseUrl(site.page).hostname

const sovrnBidReq = {
id: utils.getUniqueIdentifierStr(),
imp: sovrnImps,
site: {
page,
domain
}
};
site: site,
user: fpd.user || {}
}

if (schain) {
sovrnBidReq.source = {
Expand Down
220 changes: 117 additions & 103 deletions test/spec/modules/sovrnBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {expect} from 'chai';
import {LogError, spec} from 'modules/sovrnBidAdapter.js';
import {newBidder} from 'src/adapters/bidderFactory.js';
import {spec} from 'modules/sovrnBidAdapter.js';
import {config} from 'src/config.js';
import * as utils from 'src/utils.js'

const ENDPOINT = `https://ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$`;

const adUnitBidRequest = {
'bidder': 'sovrn',
'params': {
'tagid': '403370'
'tagid': 403370
},
'adUnitCode': 'adunit-code',
'sizes': [
Expand All @@ -18,82 +19,61 @@ const adUnitBidRequest = {
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
}
const bidderRequest = {
refererInfo: {
referer: 'http://example.com/page.html',
}
};

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

describe('isBidRequestValid', function () {
const bid = {
'bidder': 'sovrn',
'params': {
'tagid': '403370'
},
'adUnitCode': 'adunit-code',
'sizes': [
[300, 250],
[300, 600]
],
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475',
};

it('should return true when required params found', function () {
expect(spec.isBidRequestValid(bid)).to.equal(true);
expect(spec.isBidRequestValid(adUnitBidRequest)).to.equal(true);
});

it('should return false when tagid not passed correctly', function () {
bid.params.tagid = 'ABCD';
expect(spec.isBidRequestValid(bid)).to.equal(false);
const bid = {...adUnitBidRequest}
const params = adUnitBidRequest.params
bid.params = {...params}
bid.params.tagid = 'ABCD'
expect(spec.isBidRequestValid(bid)).to.equal(false)
});

it('should return false when require params are not passed', function () {
let bid = Object.assign({}, bid);
const bid = {...adUnitBidRequest}
bid.params = {};
expect(spec.isBidRequestValid(bid)).to.equal(false);
});
});

describe('buildRequests', function () {
const bidRequests = [{
'bidder': 'sovrn',
'params': {
'tagid': '403370'
},
'adUnitCode': 'adunit-code',
'sizes': [
[300, 250],
[300, 600]
],
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
}];
const bidderRequest = {
refererInfo: {
referer: 'http://example.com/page.html',
}
};
const request = spec.buildRequests(bidRequests, bidderRequest);

it('sends bid request to our endpoint via POST', function () {
expect(request.method).to.equal('POST');
});

it('attaches source and version to endpoint URL as query params', function () {
expect(request.url).to.equal(ENDPOINT)
});

it('sets the proper banner object', function() {
const payload = JSON.parse(request.data)
expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}])
expect(payload.imp[0].banner.w).to.equal(1)
expect(payload.imp[0].banner.h).to.equal(1)
})

it('includes the ad unit code int the request', function() {
const payload = JSON.parse(request.data);
expect(payload.imp[0].adunitcode).to.equal('adunit-code')
describe('basic bid parameters', function() {
const bidRequests = [adUnitBidRequest];
const request = spec.buildRequests(bidRequests, bidderRequest);

it('sends bid request to our endpoint via POST', function () {
expect(request.method).to.equal('POST');
});

it('attaches source and version to endpoint URL as query params', function () {
expect(request.url).to.equal(ENDPOINT)
});

it('sets the proper banner object', function() {
const payload = JSON.parse(request.data)
expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}])
expect(payload.imp[0].banner.w).to.equal(1)
expect(payload.imp[0].banner.h).to.equal(1)
})

it('includes the ad unit code int the request', function() {
const payload = JSON.parse(request.data);
expect(payload.imp[0].adunitcode).to.equal('adunit-code')
})

it('converts tagid to string', function () {
expect(request.data).to.contain('"tagid":"403370"')
});
})

it('accepts a single array as a size', function() {
Expand All @@ -109,11 +89,6 @@ describe('sovrnBidAdapter', function() {
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
}]
const bidderRequest = {
refererInfo: {
referer: 'http://example.com/page.html',
}
}
const request = spec.buildRequests(singleSize, bidderRequest)
const payload = JSON.parse(request.data)
expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}])
Expand Down Expand Up @@ -149,7 +124,7 @@ describe('sovrnBidAdapter', function() {

it('sends gdpr info if exists', function () {
let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==';
let bidderRequest = {
const bidderRequest = {
'bidderCode': 'sovrn',
'auctionId': '1d1a030790a475',
'bidderRequestId': '22edbae2733bf6',
Expand All @@ -162,9 +137,9 @@ describe('sovrnBidAdapter', function() {
referer: 'http://example.com/page.html',
}
};
bidderRequest.bids = bidRequests;
bidderRequest.bids = [adUnitBidRequest];

const data = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data);
const data = JSON.parse(spec.buildRequests([adUnitBidRequest], bidderRequest).data);

expect(data.regs.ext.gdpr).to.exist.and.to.be.a('number');
expect(data.regs.ext.gdpr).to.equal(1);
Expand All @@ -173,8 +148,8 @@ describe('sovrnBidAdapter', function() {
});

it('should send us_privacy if bidderRequest has a value for uspConsent', function () {
let uspString = '1NYN';
let bidderRequest = {
const uspString = '1NYN';
const bidderRequest = {
'bidderCode': 'sovrn',
'auctionId': '1d1a030790a475',
'bidderRequestId': '22edbae2733bf6',
Expand All @@ -184,39 +159,13 @@ describe('sovrnBidAdapter', function() {
referer: 'http://example.com/page.html',
}
};
bidderRequest.bids = bidRequests;
bidderRequest.bids = [adUnitBidRequest];

const data = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data);
const data = JSON.parse(spec.buildRequests([adUnitBidRequest], bidderRequest).data);

expect(data.regs.ext['us_privacy']).to.equal(uspString);
});

it('converts tagid to string', function () {
const ivBidRequests = [{
'bidder': 'sovrn',
'params': {
'tagid': 403370,
'iv': 'vet'
},
'adUnitCode': 'adunit-code',
'sizes': [
[300, 250],
[300, 600]
],
'bidId': '30b31c1838de1e',
'bidderRequestId': '22edbae2733bf6',
'auctionId': '1d1a030790a475'
}];
const bidderRequest = {
refererInfo: {
referer: 'http://example.com/page.html',
}
};
const request = spec.buildRequests(ivBidRequests, bidderRequest);

expect(request.data).to.contain('"tagid":"403370"')
});

it('should add schain if present', function() {
const schainRequests = [{
'bidder': 'sovrn',
Expand All @@ -243,7 +192,7 @@ describe('sovrnBidAdapter', function() {
}
]
}
}].concat(bidRequests);
}].concat(adUnitBidRequest);
const bidderRequest = {
refererInfo: {
referer: 'http://example.com/page.html',
Expand Down Expand Up @@ -272,7 +221,7 @@ describe('sovrnBidAdapter', function() {
'criteoId': 'A_CRITEO_ID',
'tdid': 'SOMESORTOFID',
}
}].concat(bidRequests);
}].concat(adUnitBidRequest);
const bidderRequest = {
refererInfo: {
referer: 'http://example.com/page.html',
Expand All @@ -293,6 +242,7 @@ describe('sovrnBidAdapter', function() {
});

it('should ignore empty segments', function() {
const request = spec.buildRequests([adUnitBidRequest], bidderRequest)
const payload = JSON.parse(request.data)
expect(payload.imp[0].ext).to.be.undefined
})
Expand Down Expand Up @@ -337,6 +287,70 @@ describe('sovrnBidAdapter', function() {
const payload = JSON.parse(request.data)
expect(payload.imp[0].bidfloor).to.equal(2.00)
})
describe('First Party Data', function () {
let sandbox

beforeEach(function() {
sandbox = sinon.sandbox.create()
})
afterEach(function() {
sandbox.restore()
})
it('should provide first party data if provided', function() {
sandbox.stub(config, 'getConfig').callsFake(key => {
const cfg = {
ortb2: {
site: {
keywords: 'test keyword'
},
user: {
data: 'some user data'
}
}
};
return utils.deepAccess(cfg, key);
});
const request = spec.buildRequests([adUnitBidRequest], bidderRequest)
const payload = JSON.parse(request.data)
expect(payload.user.data).to.equal('some user data')
expect(payload.site.keywords).to.equal('test keyword')
expect(payload.site.page).to.equal('http://example.com/page.html')
expect(payload.site.domain).to.equal('example.com')
})
it('should append impression first party data', function () {
const fpdBid = {...adUnitBidRequest}
fpdBid.ortb2Imp = {
ext: {
data: {
pbadslot: 'homepage-top-rect',
adUnitSpecificAttribute: '123'
}
}
}
const request = spec.buildRequests([fpdBid], bidderRequest)
const payload = JSON.parse(request.data)
expect(payload.imp[0].ext.data.pbadslot).to.equal('homepage-top-rect')
expect(payload.imp[0].ext.data.adUnitSpecificAttribute).to.equal('123')
})
it('should not overwrite deals when impression fpd is present', function() {
const fpdBid = {...adUnitBidRequest}
fpdBid.params = {...adUnitBidRequest.params}
fpdBid.params.segments = 'seg1, seg2'
fpdBid.ortb2Imp = {
ext: {
data: {
pbadslot: 'homepage-top-rect',
adUnitSpecificAttribute: '123'
}
}
}
const request = spec.buildRequests([fpdBid], bidderRequest)
const payload = JSON.parse(request.data)
expect(payload.imp[0].ext.data.pbadslot).to.equal('homepage-top-rect')
expect(payload.imp[0].ext.data.adUnitSpecificAttribute).to.equal('123')
expect(payload.imp[0].ext.deals).to.deep.equal(['seg1', 'seg2'])
})
})
});

describe('interpretResponse', function () {
Expand Down