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

ttd bid adapter: pass on all of user/app/ortb2imp for first party data support, default imp.secure #9892

Merged
merged 5 commits into from
May 6, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
32 changes: 12 additions & 20 deletions modules/ttdBidAdapter.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 { config } from '../src/config.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import {isNumber} from '../src/utils.js';

const BIDADAPTERVERSION = 'TTD-PREBID-2022.06.28';
const BIDDER_CODE = 'ttd';
Expand Down Expand Up @@ -114,7 +115,7 @@ function getConnectionType() {
}
}

function getUser(bidderRequest) {
function getUser(bidderRequest, firstPartyData) {
let user = {};
if (bidderRequest.gdprConsent) {
utils.deepSetValue(user, 'ext.consent', bidderRequest.gdprConsent.consentString);
Expand All @@ -129,13 +130,8 @@ function getUser(bidderRequest) {
utils.deepSetValue(user, 'ext.eids', eids);
}

// gather user.data
const ortb2UserData = utils.deepAccess(bidderRequest, 'ortb2.user.data');
if (ortb2UserData && ortb2UserData.length) {
user = utils.mergeDeep(user, {
data: [...ortb2UserData]
});
};
utils.mergeDeep(user, firstPartyData.user)

return user;
}

Expand Down Expand Up @@ -163,16 +159,6 @@ function getImpression(bidRequest) {
};

const gpid = utils.deepAccess(bidRequest, 'ortb2Imp.ext.gpid');
const tid = utils.deepAccess(bidRequest, 'ortb2Imp.ext.tid');
const rwdd = utils.deepAccess(bidRequest, 'ortb2Imp.rwdd');
if (gpid || tid) {
impression.ext = {}
if (gpid) { impression.ext.gpid = gpid }
if (tid) { impression.ext.tid = tid }
}
if (rwdd) {
impression.rwdd = rwdd;
}
const tagid = gpid || bidRequest.params.placementId;
if (tagid) {
impression.tagid = tagid;
Expand All @@ -197,6 +183,11 @@ function getImpression(bidRequest) {
impression.bidfloorcur = 'USD';
}

const secure = utils.deepAccess(bidRequest, 'ortb2Imp.secure');
impression.secure = isNumber(secure) ? secure : 1

utils.mergeDeep(impression, bidRequest.ortb2Imp)

return impression;
}

Expand Down Expand Up @@ -413,9 +404,10 @@ export const spec = {
let topLevel = {
id: bidderRequest.auctionId,
imp: validBidRequests.map(bidRequest => getImpression(bidRequest)),
app: firstPartyData.app || {},
site: getSite(bidderRequest, firstPartyData),
device: getDevice(),
user: getUser(bidderRequest),
user: getUser(bidderRequest, firstPartyData),
at: 1,
cur: ['USD'],
regs: getRegs(bidderRequest),
Expand Down Expand Up @@ -466,7 +458,7 @@ export const spec = {
* @param {ttdResponseObj} bidResponse A successful response from ttd.
* @param {ServerRequest} serverRequest The result of buildRequests() that lead to this response.
* @return {Bid[]} An array of formatted bids.
*/
*/
interpretResponse: function (response, serverRequest) {
let seatBidsInResponse = utils.deepAccess(response, 'body.seatbid');
const currency = utils.deepAccess(response, 'body.cur');
Expand Down
129 changes: 127 additions & 2 deletions test/spec/modules/ttdBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,132 @@ describe('ttdBidAdapter', function () {
config.resetConfig();
expect(requestBody.imp[0].bidfloor).to.equal(bidfloor);
});

it('adds default value for secure if not set to request', function () {
const requestBody = testBuildRequests(baseBannerBidRequests, baseBidderRequest).data;
expect(requestBody.imp[0].secure).to.equal(1);
});

it('adds secure to request', function () {
let clonedBannerRequests = deepClone(baseBannerBidRequests);
clonedBannerRequests[0].ortb2Imp.secure = 0;

let requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
expect(0).to.equal(requestBody.imp[0].secure);

clonedBannerRequests[0].ortb2Imp.secure = 1;
requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;
expect(1).to.equal(requestBody.imp[0].secure);
});

it('adds all of site including first party data to request', function() {
const ortb2 = {
site: {
ext: {
data: {
firstPartyKey: 'firstPartyValue'
},
custom: 'custom_data',
custom_kvp: {
customKey: 'customValue'
}
},
search: 'test search'
}
};

let clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2};
const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data;

expect(requestBody.site.ext.data.firstPartyKey).to.equal('firstPartyValue');
expect(requestBody.site.ext.custom).to.equal('custom_data');
expect(requestBody.site.ext.custom_kvp.customKey).to.equal('customValue');
expect(requestBody.site.search).to.equal('test search')
});

it('adds all of user including first party data to request', function() {
const values = ['value', 'value2'];
const ortb2 = {
user: {
ext: {
data: {
firstPartyKey: 'firstPartyValue',
firstPartyKey2: values
},
custom: 'custom_data',
custom_kvp: {
customKey: 'customValue'
}
},
yob: 1998
}
};

let clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2};
const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data;
expect(requestBody.user.ext.data.firstPartyKey).to.equal('firstPartyValue');
expect(requestBody.user.ext.data.firstPartyKey2).to.eql(values);
expect(requestBody.user.ext.custom).to.equal('custom_data');
expect(requestBody.user.ext.custom_kvp.customKey).to.equal('customValue');
expect(requestBody.user.yob).to.equal(1998)
});

it('adds all of imp including first party data to request', function() {
const values = ['value', 'value2'];
const metric = { type: 'viewability', value: 0.8 };
let clonedBannerRequests = deepClone(baseBannerBidRequests);
clonedBannerRequests[0].ortb2Imp = {
ext: {
data: {
firstPartyKey: 'firstPartyValue',
firstPartyKey2: values
},
custom: 'custom_data',
custom_kvp: {
customKey: 'customValue'
}
},
metric: [metric],
clickbrowser: 1
};

const requestBody = testBuildRequests(clonedBannerRequests, baseBidderRequest).data;

expect(requestBody.imp[0].tagid).to.equal('1gaa015');
expect(requestBody.imp[0].ext.data.firstPartyKey).to.equal('firstPartyValue');
expect(requestBody.imp[0].ext.data.firstPartyKey2).to.eql(values);
expect(requestBody.imp[0].ext.custom).to.equal('custom_data');
expect(requestBody.imp[0].ext.custom_kvp.customKey).to.equal('customValue');
expect(requestBody.imp[0].metric[0]).to.deep.equal(metric);
expect(requestBody.imp[0].clickbrowser).to.equal(1)
});

it('adds all of app including first party data to request', function() {
const values = ['value', 'value2'];
const ortb2 = {
app: {
ext: {
data: {
firstPartyKey: 'firstPartyValue',
firstPartyKey2: values
},
custom: 'custom_data',
custom_kvp: {
customKey: 'customValue'
}
},
ver: 'v1.0'
}
};

let clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2};
const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data;
expect(requestBody.app.ext.data.firstPartyKey).to.equal('firstPartyValue');
expect(requestBody.app.ext.data.firstPartyKey2).to.eql(values);
expect(requestBody.app.ext.custom).to.equal('custom_data');
expect(requestBody.app.ext.custom_kvp.customKey).to.equal('customValue');
expect(requestBody.app.ver).to.equal('v1.0')
});
});

describe('buildRequests-banner-multiple', function () {
Expand Down Expand Up @@ -1279,8 +1405,7 @@ describe('ttdBidAdapter', function () {
}
};

const expectedBid =
{
const expectedBid = {
'requestId': '2eabb87dfbcae4',
'cpm': 13.6,
'creativeId': 'mokivv6m',
Expand Down