Skip to content

Commit

Permalink
1. Update to move pbadslot and adserver data into imp[] as opposed to…
Browse files Browse the repository at this point in the history
… parent.

2. Update to convert keywords passed through RP params to string if array found
  • Loading branch information
mmoschovas committed Jan 21, 2021
1 parent c8bd004 commit 030da98
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 29 deletions.
47 changes: 28 additions & 19 deletions modules/rubiconBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,11 @@ export const spec = {
}

const bidFpd = {
user: bidRequest.params.visitor || {},
context: bidRequest.params.inventory || {}
user: {...bidRequest.params.visitor} || {},
context: {...bidRequest.params.inventory} || {}
};

if (bidRequest.params.keywords) bidFpd.context.keywords = bidRequest.params.keywords;
if (bidRequest.params.keywords) bidFpd.context.keywords = (utils.isArray(bidRequest.params.keywords)) ? bidRequest.params.keywords.join(',') : bidRequest.params.keywords;

applyFPD(utils.mergeDeep({}, config.getConfig('fpd') || {}, bidRequest.fpd || {}, bidFpd), VIDEO, data);

Expand Down Expand Up @@ -516,11 +516,11 @@ export const spec = {
}

const bidFpd = {
user: bidRequest.params.visitor || {},
context: bidRequest.params.inventory || {}
user: {...bidRequest.params.visitor} || {},
context: {...bidRequest.params.inventory} || {}
};

if (bidRequest.params.keywords) bidFpd.context.keywords = bidRequest.params.keywords;
if (bidRequest.params.keywords) bidFpd.context.keywords = (utils.isArray(bidRequest.params.keywords)) ? bidRequest.params.keywords.join(',') : bidRequest.params.keywords;

applyFPD(utils.mergeDeep({}, config.getConfig('fpd') || {}, bidRequest.fpd || {}, bidFpd), BANNER, data);

Expand Down Expand Up @@ -885,21 +885,22 @@ function addVideoParameters(data, bidRequest) {
function applyFPD(fpd, mediaType, data) {
const map = {user: {banner: 'tg_v.', code: 'user'}, context: {banner: 'tg_i.', code: 'site'}, adserver: 'dfp_ad_unit_code'};
let obj = {};
let impData = {};
let keywords = [];
const validate = function(e, t) {
if (typeof e === 'object' && !Array.isArray(e)) {
utils.logWarn('Rubicon: Filtered FPD key: ', t, ': Expected value to be string, integer, or an array of strings/ints');
} else if (e) {
return (Array.isArray(e)) ? e.filter(value => {
if (typeof value !== 'object' && value) return value;

utils.logWarn('Rubicon: Filtered value: ', value, 'for key', t, ': Expected value to be string, integer, or an array of strings/ints');
}).toString() : e.toString();
const validate = function(prop, key) {
if (typeof prop === 'object' && !Array.isArray(prop)) {
utils.logWarn('Rubicon: Filtered FPD key: ', key, ': Expected value to be string, integer, or an array of strings/ints');
} else if (utils.isNumber(prop) || prop) {
return (Array.isArray(prop)) ? prop.filter(value => {
if (typeof value !== 'object' && (utils.isNumber(value) || value)) return value.toString();

utils.logWarn('Rubicon: Filtered value: ', value, 'for key', key, ': Expected value to be string, integer, or an array of strings/ints');
}).toString() : prop.toString();
}
};

Object.keys(fpd).filter(value => fpd[value] && map[value] && typeof fpd[value] === 'object').forEach((type) => {
obj[map[type].code] = Object.keys(fpd[type]).filter(value => fpd[type][value]).reduce((result, key) => {
obj[map[type].code] = Object.keys(fpd[type]).filter(value => utils.isNumber(fpd[type][value]) || fpd[type][value]).reduce((result, key) => {
if (key === 'keywords') {
if (!Array.isArray(fpd[type][key]) && mediaType === BANNER) fpd[type][key] = [fpd[type][key]]

Expand All @@ -911,9 +912,8 @@ function applyFPD(fpd, mediaType, data) {
} else if (key === 'adServer' || key === 'pbAdSlot') {
(key === 'adServer') ? ['name', 'adSlot'].forEach(name => {
const value = validate(fpd[type][key][name]);

if (value) utils.mergeDeep(result, {ext: {data: {adserver: {[name.toLowerCase()]: value.replace(/^\/+/, '')}}}});
}) : utils.mergeDeep(result, {ext: {data: {[key.toLowerCase()]: fpd[type][key].replace(/^\/+/, '')}}});
if (value) utils.deepSetValue(impData, `adserver.${name.toLowerCase()}`, value.replace(/^\/+/, ''))
}) : impData[key.toLowerCase()] = fpd[type][key].replace(/^\/+/, '')
} else {
utils.mergeDeep(result, {ext: {data: {[key]: fpd[type][key]}}});
}
Expand All @@ -923,6 +923,7 @@ function applyFPD(fpd, mediaType, data) {

if (mediaType === BANNER) {
let duplicate = (typeof obj[map[type].code].ext === 'object' && obj[map[type].code].ext.data) || {};

Object.keys(duplicate).forEach((key) => {
const val = (key === 'adserver') ? duplicate.adserver.adslot : validate(duplicate[key], key);

Expand All @@ -931,6 +932,14 @@ function applyFPD(fpd, mediaType, data) {
}
});

Object.keys(impData).forEach((key) => {
if (mediaType === BANNER) {
(map[key]) ? data[`tg_i.${map[key]}`] = impData[key].adslot : data[`tg_i.${key.toLowerCase()}`] = impData[key];
} else {
utils.mergeDeep(data.imp[0], {ext: {context: {data: {[key]: impData[key]}}}});
}
});

if (mediaType === BANNER) {
let kw = validate(keywords, 'keywords');
if (kw) data.kw = kw;
Expand Down
20 changes: 10 additions & 10 deletions test/spec/modules/rubiconBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ describe('the rubicon adapter', function () {

it('should merge first party data from getConfig with the bid params, if present', () => {
const context = {
keywords: ['e', 'f'],
keywords: 'e,f',
rating: '4-star',
data: {
page: 'home'
Expand All @@ -838,7 +838,7 @@ describe('the rubicon adapter', function () {
gender: 'M',
yob: '1984',
geo: {country: 'ca'},
keywords: ['d'],
keywords: 'd',
data: {
age: 40
}
Expand All @@ -855,7 +855,7 @@ describe('the rubicon adapter', function () {
});

const expectedQuery = {
'kw': 'e,f,a,b,c,d',
'kw': 'a,b,c,d',
'tg_v.ucat': 'new',
'tg_v.lastsearch': 'iphone',
'tg_v.likes': 'sports,video games',
Expand Down Expand Up @@ -1875,14 +1875,14 @@ describe('the rubicon adapter', function () {
data: {
page: 'home'
},
keywords: ['e', 'f'],
keywords: 'e,f',
rating: '4-star'
};
const user = {
data: {
age: 31
},
keywords: ['d'],
keywords: 'd',
gender: 'M',
yob: '1984',
geo: {country: 'ca'}
Expand Down Expand Up @@ -1910,8 +1910,8 @@ describe('the rubicon adapter', function () {
delete expected.site.keywords;
delete expected.user.keywords;

expect(request.data.site.keywords).to.deep.equal(['e', 'f', 'a', 'b', 'c']);
expect(request.data.user.keywords).to.deep.equal(['d']);
expect(request.data.site.keywords).to.deep.equal('a,b,c');
expect(request.data.user.keywords).to.deep.equal('d');
expect(request.data.site.ext.data).to.deep.equal(expected.site);
expect(request.data.user.ext.data).to.deep.equal(expected.user);
});
Expand Down Expand Up @@ -1945,7 +1945,7 @@ describe('the rubicon adapter', function () {
);

const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
expect(request.data.site.ext.data.pbadslot).to.equal('1234567890');
expect(request.data.imp[0].ext.context.data.pbadslot).to.equal('1234567890');
});

it('should include GAM ad unit in bid request', function () {
Expand All @@ -1964,8 +1964,8 @@ describe('the rubicon adapter', function () {
);

const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest);
expect(request.data.site.ext.data.adserver.adslot).to.equal('1234567890');
expect(request.data.site.ext.data.adserver.name).to.equal('adServerName1');
expect(request.data.imp[0].ext.context.data.adserver.adslot).to.equal('1234567890');
expect(request.data.imp[0].ext.context.data.adserver.name).to.equal('adServerName1');
});

it('should use the integration type provided in the config instead of the default', () => {
Expand Down

0 comments on commit 030da98

Please sign in to comment.