Skip to content

Commit

Permalink
AdKernelADN adapter GDPR support (prebid#2624)
Browse files Browse the repository at this point in the history
Ad units size issue fix
  • Loading branch information
ckbo3hrk authored and StefanWallin committed Sep 28, 2018
1 parent 76aae39 commit ef4d66f
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 48 deletions.
32 changes: 20 additions & 12 deletions modules/adkernelAdnBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ function buildImp(bidRequest) {
};
if (bidRequest.mediaType === BANNER || utils.deepAccess(bidRequest, `mediaTypes.banner`) ||
(bidRequest.mediaTypes === undefined && bidRequest.mediaType === undefined)) {
let sizes = canonicalizeSizesArray(utils.deepAccess(bidRequest, `mediaTypes.banner.sizes`) || bidRequest.sizes);
let sizes = canonicalizeSizesArray(bidRequest.sizes);
imp.banner = {
format: utils.parseSizesInput(sizes)
}
} else if (bidRequest.mediaType === VIDEO || utils.deepAccess(bidRequest, `mediaTypes.video`)) {
let size = utils.deepAccess(bidRequest, `mediaTypes.video.playerSize`) || canonicalizeSizesArray(bidRequest.sizes)[0];
let size = canonicalizeSizesArray(bidRequest.sizes)[0];
imp.video = {
w: size[0],
h: size[1],
Expand Down Expand Up @@ -54,9 +54,9 @@ function canonicalizeSizesArray(sizes) {
return sizes;
}

function buildRequestParams(auctionId, transactionId, tags) {
function buildRequestParams(tags, auctionId, transactionId, gdprConsent) {
let loc = utils.getTopWindowLocation();
return {
let req = {
id: auctionId,
tid: transactionId,
site: {
Expand All @@ -66,6 +66,17 @@ function buildRequestParams(auctionId, transactionId, tags) {
},
imp: tags
};

if (gdprConsent && (gdprConsent.gdprApplies !== undefined || gdprConsent.consentString !== undefined)) {
req.user = {};
if (gdprConsent.gdprApplies !== undefined) {
req.user.gdpr = ~~(gdprConsent.gdprApplies);
}
if (gdprConsent.consentString !== undefined) {
req.user.consent = gdprConsent.consentString;
}
}
return req;
}

function buildBid(tag) {
Expand All @@ -91,19 +102,15 @@ function buildBid(tag) {
}

export const spec = {

code: 'adkernelAdn',

supportedMediaTypes: [BANNER, VIDEO],

isBidRequestValid: function(bidRequest) {
return 'params' in bidRequest && (typeof bidRequest.params.host === 'undefined' || typeof bidRequest.params.host === 'string') &&
typeof bidRequest.params.pubId === 'number';
},

buildRequests: function(bidRequests) {
let transactionId;
let auctionId;
buildRequests: function(bidRequests, bidderRequest) {
let dispatch = bidRequests.map(buildImp)
.reduce((acc, curr, index) => {
let bidRequest = bidRequests[index];
Expand All @@ -112,14 +119,15 @@ export const spec = {
acc[host] = acc[host] || {};
acc[host][pubId] = acc[host][pubId] || [];
acc[host][pubId].push(curr);
transactionId = bidRequest.transactionId;
auctionId = bidRequest.bidderRequestId;
return acc;
}, {});
let auctionId = bidderRequest.auctionId;
let gdprConsent = bidderRequest.gdprConsent;
let transactionId = bidderRequest.transactionId;
let requests = [];
Object.keys(dispatch).forEach(host => {
Object.keys(dispatch[host]).forEach(pubId => {
let request = buildRequestParams(auctionId, transactionId, dispatch[host][pubId]);
let request = buildRequestParams(dispatch[host][pubId], auctionId, transactionId, gdprConsent);
requests.push({
method: 'POST',
url: `//${host}/tag?account=${pubId}&pb=1${isRtbDebugEnabled() ? '&debug=1' : ''}`,
Expand Down
104 changes: 68 additions & 36 deletions test/spec/modules/adkernelAdnBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ describe('AdkernelAdn adapter', () => {
bidder: 'adkernelAdn',
transactionId: 'transact0',
bidderRequestId: 'req0',
auctionId: '5c66da22-426a-4bac-b153-77360bef5337',
bidId: 'bidid_1',
params: {
pubId: 1
Expand All @@ -16,8 +17,9 @@ describe('AdkernelAdn adapter', () => {
},
bid2_pub1 = {
bidder: 'adkernelAdn',
transactionId: 'transact1',
bidderRequestId: 'req1',
transactionId: 'transact0',
bidderRequestId: 'req0',
auctionId: '5c66da22-426a-4bac-b153-77360bef5337',
bidId: 'bidid_2',
params: {
pubId: 1
Expand All @@ -29,6 +31,7 @@ describe('AdkernelAdn adapter', () => {
bidder: 'adkernelAdn',
transactionId: 'transact2',
bidderRequestId: 'req1',
auctionId: '5c66da22-426a-4bac-b153-77360bef5337',
bidId: 'bidid_3',
params: {
pubId: 7,
Expand All @@ -40,6 +43,7 @@ describe('AdkernelAdn adapter', () => {
bidder: 'adkernelAdn',
transactionId: 'transact3',
bidderRequestId: 'req1',
auctionId: '5c66da22-426a-4bac-b153-77360bef5337',
bidId: 'bidid_4',
mediaType: 'video',
sizes: [640, 300],
Expand All @@ -56,7 +60,9 @@ describe('AdkernelAdn adapter', () => {
bidder: 'adkernelAdn',
transactionId: 'transact3',
bidderRequestId: 'req1',
auctionId: '5c66da22-426a-4bac-b153-77360bef5337',
bidId: 'bidid_5',
sizes: [[1920, 1080]],
mediaTypes: {
video: {
playerSize: [1920, 1080],
Expand Down Expand Up @@ -106,8 +112,7 @@ describe('AdkernelAdn adapter', () => {

describe('input parameters validation', () => {
it('empty request shouldn\'t generate exception', () => {
expect(spec.isBidRequestValid({
bidderCode: 'adkernelAdn'
expect(spec.isBidRequestValid({bidderCode: 'adkernelAdn'
})).to.be.equal(false);
});
it('request without pubid should be ignored', () => {
Expand All @@ -130,25 +135,32 @@ describe('AdkernelAdn adapter', () => {
});
});

describe('banner request building', () => {
let pbRequest;
let tagRequest;

before(() => {
let mock = sinon.stub(utils, 'getTopWindowLocation').callsFake(() => {
return {
protocol: 'https:',
hostname: 'example.com',
host: 'example.com',
pathname: '/index.html',
href: 'https://example.com/index.html'
};
});
pbRequest = spec.buildRequests([bid1_pub1])[0];
tagRequest = JSON.parse(pbRequest.data);
mock.restore();
function buildRequest(bidRequests, bidderRequest = {}) {
let mock = sinon.stub(utils, 'getTopWindowLocation').callsFake(() => {
return {
protocol: 'https:',
hostname: 'example.com',
host: 'example.com',
pathname: '/index.html',
href: 'https://example.com/index.html'
};
});

bidderRequest.auctionId = bidRequests[0].auctionId;
bidderRequest.transactionId = bidRequests[0].transactionId;
bidderRequest.bidderRequestId = bidRequests[0].bidderRequestId;

let pbRequests = spec.buildRequests(bidRequests, bidderRequest);
let tagRequests = pbRequests.map(r => JSON.parse(r.data));
mock.restore();

return [pbRequests, tagRequests];
}

describe('banner request building', () => {
let [_, tagRequests] = buildRequest([bid1_pub1]);
let tagRequest = tagRequests[0];

it('should have request id', () => {
expect(tagRequest).to.have.property('id');
});
Expand All @@ -169,11 +181,35 @@ describe('AdkernelAdn adapter', () => {
expect(tagRequest.site).to.have.property('page', 'https://example.com/index.html');
expect(tagRequest.site).to.have.property('secure', 1);
});

it('should not have user object', () => {
expect(tagRequest).to.not.have.property('user');
});

it('shouldn\'t contain gdpr-related information for default request', () => {
let [_, tagRequests] = buildRequest([bid1_pub1]);
expect(tagRequests[0]).to.not.have.property('user');
});

it('should contain gdpr-related information if consent is configured', () => {
let [_, bidRequests] = buildRequest([bid1_pub1],
{gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}});
expect(bidRequests[0]).to.have.property('user');
expect(bidRequests[0].user).to.have.property('gdpr', 1);
expect(bidRequests[0].user).to.have.property('consent', 'test-consent-string');
});

it('should\'t contain consent string if gdpr isn\'t applied', () => {
let [_, bidRequests] = buildRequest([bid1_pub1], {gdprConsent: {gdprApplies: false}});
expect(bidRequests[0]).to.have.property('user');
expect(bidRequests[0].user).to.have.property('gdpr', 0);
expect(bidRequests[0].user).to.not.have.property('consent');
});
});

describe('video request building', () => {
let pbRequest = spec.buildRequests([bid_video1, bid_video2])[0];
let tagRequest = JSON.parse(pbRequest.data);
let [_, tagRequests] = buildRequest([bid_video1, bid_video2]);
let tagRequest = tagRequests[0];

it('should have video object', () => {
expect(tagRequest.imp[0]).to.have.property('video');
Expand All @@ -193,24 +229,20 @@ describe('AdkernelAdn adapter', () => {

describe('requests routing', () => {
it('should issue a request for each publisher', () => {
let pbRequests = spec.buildRequests([bid1_pub1, bid_video1]);
let [pbRequests, tagRequests] = buildRequest([bid1_pub1, bid_video1]);
expect(pbRequests).to.have.length(2);
expect(pbRequests[0].url).to.have.string(`account=${bid1_pub1.params.pubId}`);
expect(pbRequests[1].url).to.have.string(`account=${bid1_pub2.params.pubId}`);
let tagRequest1 = JSON.parse(pbRequests[0].data);
let tagRequest2 = JSON.parse(pbRequests[1].data);
expect(tagRequest1.imp).to.have.length(1);
expect(tagRequest2.imp).to.have.length(1);
expect(tagRequests[0].imp).to.have.length(1);
expect(tagRequests[1].imp).to.have.length(1);
});
it('should issue a request for each host', () => {
let pbRequests = spec.buildRequests([bid1_pub1, bid1_pub2]);
let [pbRequests, tagRequests] = buildRequest([bid1_pub1, bid1_pub2]);
expect(pbRequests).to.have.length(2);
expect(pbRequests[0].url).to.have.string('//tag.adkernel.com/tag');
expect(pbRequests[1].url).to.have.string(`//${bid1_pub2.params.host}/tag`);
let tagRequest1 = JSON.parse(pbRequests[0].data);
let tagRequest2 = JSON.parse(pbRequests[1].data);
expect(tagRequest1.imp).to.have.length(1);
expect(tagRequest2.imp).to.have.length(1);
expect(tagRequests[0].imp).to.have.length(1);
expect(tagRequests[1].imp).to.have.length(1);
});
});

Expand Down Expand Up @@ -257,11 +289,11 @@ describe('AdkernelAdn adapter', () => {
expect(syncs[0]).to.have.property('url', 'https://dsp.adkernel.com/sync');
});
it('should handle user-sync only response', () => {
let request = spec.buildRequests([bid1_pub1])[0];
let resp = spec.interpretResponse({body: usersyncOnlyResponse}, request);
let [pbRequests, tagRequests] = buildRequest([bid1_pub1]);
let resp = spec.interpretResponse({body: usersyncOnlyResponse}, pbRequests[0]);
expect(resp).to.have.length(0);
});
it('shouldn\' fail in empty response', () => {
it('shouldn\' fail on empty response', () => {
let syncs = spec.getUserSyncs({iframeEnabled: true}, [{body: ''}]);
expect(syncs).to.have.length(0);
});
Expand Down

0 comments on commit ef4d66f

Please sign in to comment.