Skip to content

Commit

Permalink
Ad partner Bid Adapter: advertiser domains for Prebid 5 compliance (#…
Browse files Browse the repository at this point in the history
…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
3 people authored Aug 26, 2021
1 parent 4f76c4f commit 61f4090
Show file tree
Hide file tree
Showing 3 changed files with 374 additions and 1 deletion.
131 changes: 131 additions & 0 deletions modules/adpartnerBidAdapter.js
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);
2 changes: 1 addition & 1 deletion modules/adpartnerBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ About us : https://adpartner.pro
{
bidder: "adpartner",
params: {
unitId: 5809
unitId: 6698
}
}
]
Expand Down
242 changes: 242 additions & 0 deletions test/spec/modules/adpartnerBidAdapter_spec.js
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));
});
});
});

0 comments on commit 61f4090

Please sign in to comment.