Skip to content

Commit 2f6bf3e

Browse files
GoncakkdDecayConstant
authored andcommitted
Visx bid adapter: import utilities and retrieve data from user on ortb2 (prebid#11860)
* AF-3740 retrieved topics data from user on ortb2 * AF-3740 kept old user data * AF-3740 added some checks for user data * AF-3740 used mergeDeep for merging user objects * AF-3740 provided unit tests for ortb2 data * AF-3740 moved some functionality to utils and used for avoiding duplication * AF-3740 provided unit tests
1 parent e3d3f99 commit 2f6bf3e

File tree

7 files changed

+288
-59
lines changed

7 files changed

+288
-59
lines changed

libraries/processResponse/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { logError } from '../../src/utils.js';
2+
3+
export function getBidFromResponse(respItem, LOG_ERROR_MESS) {
4+
if (!respItem) {
5+
logError(LOG_ERROR_MESS.emptySeatbid);
6+
} else if (!respItem.bid) {
7+
logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
8+
} else if (!respItem.bid[0]) {
9+
logError(LOG_ERROR_MESS.noBid);
10+
}
11+
return respItem && respItem.bid && respItem.bid[0];
12+
}

modules/carodaBidAdapter.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
deepSetValue,
99
logError,
1010
mergeDeep,
11-
parseSizesInput
11+
sizeTupleToRtbSize,
12+
sizesToSizeTuples
1213
} from '../src/utils.js';
1314
import { config } from '../src/config.js';
1415

@@ -195,13 +196,7 @@ function getImps (validBidRequests, common) {
195196
};
196197
const bannerParams = deepAccess(bid, 'mediaTypes.banner');
197198
if (bannerParams && bannerParams.sizes) {
198-
const sizes = parseSizesInput(bannerParams.sizes);
199-
const format = sizes.map(size => {
200-
const [width, height] = size.split('x');
201-
const w = parseInt(width, 10);
202-
const h = parseInt(height, 10);
203-
return { w, h };
204-
});
199+
const format = sizesToSizeTuples(bannerParams.sizes).map(sizeTupleToRtbSize);
205200
imp.banner = {
206201
format
207202
};

modules/gridBidAdapter.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Renderer } from '../src/Renderer.js';
1515
import { VIDEO, BANNER } from '../src/mediaTypes.js';
1616
import { config } from '../src/config.js';
1717
import { getStorageManager } from '../src/storageManager.js';
18+
import { getBidFromResponse } from '../libraries/processResponse/index.js';
1819

1920
/**
2021
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
@@ -441,7 +442,7 @@ export const spec = {
441442

442443
if (!errorMessage && serverResponse.seatbid) {
443444
serverResponse.seatbid.forEach(respItem => {
444-
_addBidResponse(_getBidFromResponse(respItem), bidRequest, bidResponses, RendererConst, bidderCode);
445+
_addBidResponse(getBidFromResponse(respItem, LOG_ERROR_MESS), bidRequest, bidResponses, RendererConst, bidderCode);
445446
});
446447
}
447448
if (errorMessage) logError(errorMessage);
@@ -512,17 +513,6 @@ function _getFloor (mediaTypes, bid) {
512513
return floor;
513514
}
514515

515-
function _getBidFromResponse(respItem) {
516-
if (!respItem) {
517-
logError(LOG_ERROR_MESS.emptySeatbid);
518-
} else if (!respItem.bid) {
519-
logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
520-
} else if (!respItem.bid[0]) {
521-
logError(LOG_ERROR_MESS.noBid);
522-
}
523-
return respItem && respItem.bid && respItem.bid[0];
524-
}
525-
526516
function _addBidResponse(serverBid, bidRequest, bidResponses, RendererConst, bidderCode) {
527517
if (!serverBid) return;
528518
let errorMessage;

modules/luponmediaBidAdapter.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import {
99
logError,
1010
logMessage,
1111
logWarn,
12-
parseSizesInput
12+
parseSizesInput,
13+
sizeTupleToRtbSize,
14+
sizesToSizeTuples
1315
} from '../src/utils.js';
1416
import {registerBidder} from '../src/adapters/bidderFactory.js';
1517
import {config} from '../src/config.js';
@@ -271,16 +273,8 @@ function newOrtbBidRequest(bidRequest, bidderRequest, currentImps) {
271273
let bannerSizes = [];
272274

273275
if (bannerParams && bannerParams.sizes) {
274-
const sizes = parseSizesInput(bannerParams.sizes);
275-
276276
// get banner sizes in form [{ w: <int>, h: <int> }, ...]
277-
const format = sizes.map(size => {
278-
const [ width, height ] = size.split('x');
279-
const w = parseInt(width, 10);
280-
const h = parseInt(height, 10);
281-
return { w, h };
282-
});
283-
277+
const format = sizesToSizeTuples(bannerParams.sizes).map(sizeTupleToRtbSize);
284278
bannerSizes = format;
285279
}
286280

modules/visxBidAdapter.js

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import {deepAccess, logError, parseSizesInput, triggerPixel} from '../src/utils.js';
1+
import {deepAccess, logError, mergeDeep, parseSizesInput, sizeTupleToRtbSize, sizesToSizeTuples, triggerPixel} from '../src/utils.js';
22
import {registerBidder} from '../src/adapters/bidderFactory.js';
33
import {config} from '../src/config.js';
44
import {BANNER, VIDEO} from '../src/mediaTypes.js';
55
import {INSTREAM as VIDEO_INSTREAM} from '../src/video.js';
66
import {getStorageManager} from '../src/storageManager.js';
77
import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js';
8+
import { getBidFromResponse } from '../libraries/processResponse/index.js';
89

910
const BIDDER_CODE = 'visx';
1011
const GVLID = 154;
@@ -69,6 +70,7 @@ export const spec = {
6970
let payloadSite;
7071
let payloadRegs;
7172
let payloadContent;
73+
let payloadUser;
7274

7375
if (currencyWhiteList.indexOf(currency) === -1) {
7476
logError(LOG_ERROR_MESS.notAllowedCurrency + currency);
@@ -116,6 +118,24 @@ export const spec = {
116118

117119
const { ortb2 } = bidderRequest;
118120
const { device, site, regs, content } = ortb2;
121+
const userOrtb2 = ortb2.user;
122+
let user;
123+
let userReq;
124+
const vads = _getUserId();
125+
if (payloadUserEids || payload.gdpr_consent || vads) {
126+
user = {
127+
ext: {
128+
...(payloadUserEids && { eids: payloadUserEids }),
129+
...(payload.gdpr_consent && { consent: payload.gdpr_consent }),
130+
...(vads && { vads })
131+
}
132+
};
133+
}
134+
if (user) {
135+
userReq = mergeDeep(user, userOrtb2);
136+
} else {
137+
userReq = userOrtb2;
138+
}
119139
if (device) {
120140
payloadDevice = device;
121141
}
@@ -128,6 +148,9 @@ export const spec = {
128148
if (content) {
129149
payloadContent = content;
130150
}
151+
if (userReq) {
152+
payloadUser = userReq;
153+
}
131154
}
132155

133156
const tmax = timeout;
@@ -139,14 +162,6 @@ export const spec = {
139162
}
140163
};
141164

142-
const vads = _getUserId();
143-
const user = {
144-
ext: {
145-
...(payloadUserEids && { eids: payloadUserEids }),
146-
...(payload.gdpr_consent && { consent: payload.gdpr_consent }),
147-
...(vads && { vads })
148-
}
149-
};
150165
if (payloadRegs === undefined) {
151166
payloadRegs = ('gdpr_applies' in payload) && {
152167
ext: {
@@ -161,7 +176,7 @@ export const spec = {
161176
tmax,
162177
cur: [currency],
163178
source,
164-
...(Object.keys(user.ext).length && { user }),
179+
...(payloadUser && { user: payloadUser }),
165180
...(payloadRegs && {regs: payloadRegs}),
166181
...(payloadDevice && { device: payloadDevice }),
167182
...(payloadSite && { site: payloadSite }),
@@ -190,7 +205,7 @@ export const spec = {
190205

191206
if (!errorMessage && serverResponse.seatbid) {
192207
serverResponse.seatbid.forEach(respItem => {
193-
_addBidResponse(_getBidFromResponse(respItem), bidsMap, currency, bidResponses);
208+
_addBidResponse(getBidFromResponse(respItem, LOG_ERROR_MESS), bidsMap, currency, bidResponses);
194209
});
195210
}
196211
if (errorMessage) logError(errorMessage);
@@ -260,13 +275,7 @@ function makeBanner(bannerParams) {
260275
if (bannerSizes) {
261276
const sizes = parseSizesInput(bannerSizes);
262277
if (sizes.length) {
263-
const format = sizes.map(size => {
264-
const [ width, height ] = size.split('x');
265-
const w = parseInt(width, 10);
266-
const h = parseInt(height, 10);
267-
return { w, h };
268-
});
269-
278+
const format = sizesToSizeTuples(bannerSizes).map(sizeTupleToRtbSize);
270279
return { format };
271280
}
272281
}
@@ -306,17 +315,6 @@ function buildImpObject(bid) {
306315
}
307316
}
308317

309-
function _getBidFromResponse(respItem) {
310-
if (!respItem) {
311-
logError(LOG_ERROR_MESS.emptySeatbid);
312-
} else if (!respItem.bid) {
313-
logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem));
314-
} else if (!respItem.bid[0]) {
315-
logError(LOG_ERROR_MESS.noBid);
316-
}
317-
return respItem && respItem.bid && respItem.bid[0];
318-
}
319-
320318
function _addBidResponse(serverBid, bidsMap, currency, bidResponses) {
321319
if (!serverBid) return;
322320
let errorMessage;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { getBidFromResponse } from '../../../libraries/processResponse/index.js';
2+
import {expect} from 'chai/index.js';
3+
4+
describe('processResponse', function () {
5+
const respItem = {
6+
'bid': [
7+
{
8+
'price': 0.504,
9+
'ext': {
10+
'visx': {
11+
'events': {
12+
'runtime': '//t.visx.net/track/status/RFTFjZflStSUyuXuyT2IKOZMVPUIiPkzebpPWYwKvNkE_IybYfFxk2P5feBnt9LhiR7291KTG11JjrnyHyhVKfolH_VRCmGppbnHXHfHJ9AgNqjhFB_yTg3m18wGO9k4LOddGAg3mk8qc5zYEIzNsPFnZzos1EkHh5WNs0EjrBpwCgTERUqM3PJD_Zy60nMDA-LCuq-Z4JNBGC_GHx4LwvwXipQsjdGHS-HkqHHf9sES45OlRrW4wMf69dsmey1gvwqFAhJwii2lzo9wfOohLCMRa3Vxd-zvzx-uw71maWOyKnJXWiP6c5xkyrfV4gukNYaDUgrHc0mA0yhqyiHxe8KzEl32rxQXJRCg4FoJcJ1g9jmpZQBnIh2QrKm5iC159elwzwf31_v3Uw97Zpek8j0CCLa8FjxSjvXm1Mq8x4jcwlt0ngfWU6WwyyKwX_GMbKWuAL_nrfxSvs1hZCb4eunEFyXb2lN2olWo8ezMEzZ8YRxF_mx0hDB3NXyV0Tb4b6KXQq7tvxV-1rKPRt7DySRTbLPht0hO3mjTHxutfihnuL6ROEr372gSAiDodnbdCq_lPsCsUSEpG7DmN-4In10uSp2MemjfbqI6tllOCO-j6Pm9mhdl_rT4anHmRG2DG_dLsfD7pLaAsgf2zl2bpawhxxLVjTxikoWjNKAvr_GNh4adHGj5EHbqaBaHovB573Yk-koHkyBNrebeiy-1-Knc28MWOpFi9XKjNsXx756jAXLx2H098ptaXF3mFiuT2Iv6sTVjqOI/{STATUS_CODE}'
13+
}
14+
},
15+
'prebid': {
16+
'events': {
17+
'pending': '//t.visx.net/track/pending/RFTFjZflStSUyuXuyT2IKOZMVPUIiPkzebpPWYwKvNkE_IybYfFxk2P5feBnt9LhiR7291KTG11JjrnyHyhVKfolH_VRCmGppbnHXHfHJ9AgNqjhFB_yTg3m18wGO9k4LOddGAg3mk8qc5zYEIzNsPFnZzos1EkHh5WNs0EjrBpwCgTERUqM3PJD_Zy60nMDA-LCuq-Z4JNBGC_GHx4LwvwXipQsjdGHS-HkqHHf9sES45OlRrW4wMf69dsmey1gvwqFAhJwii2lzo9wfOohLCMRa3Vxd-zvzx-uw71maWOyKnJXWiP6c5xkyrfV4gukNYaDUgrHc0mA0yhqyiHxe8KzEl32rxQXJRCg4FoJcJ1g9jmpZQBnIh2QrKm5iC159elwzwf31_v3Uw97Zpek8j0CCLa8FjxSjvXm1Mq8x4jcwlt0ngfWU6WwyyKwX_GMbKWuAL_nrfxSvs1hZCb4eunEFyXb2lN2olWo8ezMEzZ8YRxF_mx0hDB3NXyV0Tb4b6KXQq7tvxV-1rKPRt7DySRTbLPht0hO3mjTHxutfihnuL6ROEr372gSAiDodnbdCq_lPsCsUSEpG7DmN-4In10uSp2MemjfbqI6tllOCO-j6Pm9mhdl_rT4anHmRG2DG_dLsfD7pLaAsgf2zl2bpawhxxLVjTxikoWjNKAvr_GNh4adHGj5EHbqaBaHovB573Yk-koHkyBNrebeiy-1-Knc28MWOpFi9XKjNsXx756jAXLx2H098ptaXF3mFiuT2Iv6sTVjqOI/',
18+
'win': '//t.visx.net/track/win/RFTFjZflStSUyuXuyT2IKOZMVPUIiPkzebpPWYwKvNkE_IybYfFxk2P5feBnt9LhiR7291KTG11JjrnyHyhVKfolH_VRCmGppbnHXHfHJ9AgNqjhFB_yTg3m18wGO9k4LOddGAg3mk8qc5zYEIzNsPFnZzos1EkHh5WNs0EjrBpwCgTERUqM3PJD_Zy60nMDA-LCuq-Z4JNBGC_GHx4LwvwXipQsjdGHS-HkqHHf9sES45OlRrW4wMf69dsmey1gvwqFAhJwii2lzo9wfOohLCMRa3Vxd-zvzx-uw71maWOyKnJXWiP6c5xkyrfV4gukNYaDUgrHc0mA0yhqyiHxe8KzEl32rxQXJRCg4FoJcJ1g9jmpZQBnIh2QrKm5iC159elwzwf31_v3Uw97Zpek8j0CCLa8FjxSjvXm1Mq8x4jcwlt0ngfWU6WwyyKwX_GMbKWuAL_nrfxSvs1hZCb4eunEFyXb2lN2olWo8ezMEzZ8YRxF_mx0hDB3NXyV0Tb4b6KXQq7tvxV-1rKPRt7DySRTbLPht0hO3mjTHxutfihnuL6ROEr372gSAiDodnbdCq_lPsCsUSEpG7DmN-4In10uSp2MemjfbqI6tllOCO-j6Pm9mhdl_rT4anHmRG2DG_dLsfD7pLaAsgf2zl2bpawhxxLVjTxikoWjNKAvr_GNh4adHGj5EHbqaBaHovB573Yk-koHkyBNrebeiy-1-Knc28MWOpFi9XKjNsXx756jAXLx2H098ptaXF3mFiuT2Iv6sTVjqOI/',
19+
'bid_timeout': '//t.visx.net/track/bid_timeout/RFTFjZflStSUyuXuyT2IKOZMVPUIiPkzebpPWYwKvNkE_IybYfFxk2P5feBnt9LhiR7291KTG11JjrnyHyhVKfolH_VRCmGppbnHXHfHJ9AgNqjhFB_yTg3m18wGO9k4LOddGAg3mk8qc5zYEIzNsPFnZzos1EkHh5WNs0EjrBpwCgTERUqM3PJD_Zy60nMDA-LCuq-Z4JNBGC_GHx4LwvwXipQsjdGHS-HkqHHf9sES45OlRrW4wMf69dsmey1gvwqFAhJwii2lzo9wfOohLCMRa3Vxd-zvzx-uw71maWOyKnJXWiP6c5xkyrfV4gukNYaDUgrHc0mA0yhqyiHxe8KzEl32rxQXJRCg4FoJcJ1g9jmpZQBnIh2QrKm5iC159elwzwf31_v3Uw97Zpek8j0CCLa8FjxSjvXm1Mq8x4jcwlt0ngfWU6WwyyKwX_GMbKWuAL_nrfxSvs1hZCb4eunEFyXb2lN2olWo8ezMEzZ8YRxF_mx0hDB3NXyV0Tb4b6KXQq7tvxV-1rKPRt7DySRTbLPht0hO3mjTHxutfihnuL6ROEr372gSAiDodnbdCq_lPsCsUSEpG7DmN-4In10uSp2MemjfbqI6tllOCO-j6Pm9mhdl_rT4anHmRG2DG_dLsfD7pLaAsgf2zl2bpawhxxLVjTxikoWjNKAvr_GNh4adHGj5EHbqaBaHovB573Yk-koHkyBNrebeiy-1-Knc28MWOpFi9XKjNsXx756jAXLx2H098ptaXF3mFiuT2Iv6sTVjqOI/',
20+
'runtime': '//t.visx.net/track/status/RFTFjZflStSUyuXuyT2IKOZMVPUIiPkzebpPWYwKvNkE_IybYfFxk2P5feBnt9LhiR7291KTG11JjrnyHyhVKfolH_VRCmGppbnHXHfHJ9AgNqjhFB_yTg3m18wGO9k4LOddGAg3mk8qc5zYEIzNsPFnZzos1EkHh5WNs0EjrBpwCgTERUqM3PJD_Zy60nMDA-LCuq-Z4JNBGC_GHx4LwvwXipQsjdGHS-HkqHHf9sES45OlRrW4wMf69dsmey1gvwqFAhJwii2lzo9wfOohLCMRa3Vxd-zvzx-uw71maWOyKnJXWiP6c5xkyrfV4gukNYaDUgrHc0mA0yhqyiHxe8KzEl32rxQXJRCg4FoJcJ1g9jmpZQBnIh2QrKm5iC159elwzwf31_v3Uw97Zpek8j0CCLa8FjxSjvXm1Mq8x4jcwlt0ngfWU6WwyyKwX_GMbKWuAL_nrfxSvs1hZCb4eunEFyXb2lN2olWo8ezMEzZ8YRxF_mx0hDB3NXyV0Tb4b6KXQq7tvxV-1rKPRt7DySRTbLPht0hO3mjTHxutfihnuL6ROEr372gSAiDodnbdCq_lPsCsUSEpG7DmN-4In10uSp2MemjfbqI6tllOCO-j6Pm9mhdl_rT4anHmRG2DG_dLsfD7pLaAsgf2zl2bpawhxxLVjTxikoWjNKAvr_GNh4adHGj5EHbqaBaHovB573Yk-koHkyBNrebeiy-1-Knc28MWOpFi9XKjNsXx756jAXLx2H098ptaXF3mFiuT2Iv6sTVjqOI/{STATUS_CODE}'
21+
},
22+
'meta': {
23+
'mediaType': 'banner'
24+
}
25+
}
26+
},
27+
'impid': '2b642c27bdcf8f',
28+
'auid': 929004,
29+
'h': 250,
30+
'cur': 'EUR',
31+
'adomain': [
32+
''
33+
],
34+
'w': 300,
35+
'id': '9b6c7e04-0a09-4add-8ba9-0c8b98304de3'
36+
}
37+
],
38+
'seat': '1429601'
39+
};
40+
const LOG_ERROR_MESS = {
41+
'noAuid': 'Bid from response has no auid parameter - ',
42+
'noAdm': 'Bid from response has no adm parameter - ',
43+
'noBid': 'Array of bid objects is empty',
44+
'noImpId': 'Bid from response has no impid parameter - ',
45+
'noPlacementCode': 'Can\'t find in requested bids the bid with auid - ',
46+
'emptyUids': 'Uids should not be empty',
47+
'emptySeatbid': 'Seatbid array from response has an empty item',
48+
'emptyResponse': 'Response is empty',
49+
'hasEmptySeatbidArray': 'Response has empty seatbid array',
50+
'hasNoArrayOfBids': 'Seatbid from response has no array of bid objects - ',
51+
'notAllowedCurrency': 'Currency is not supported - ',
52+
'currencyMismatch': 'Currency from the request is not match currency from the response - ',
53+
'onlyVideoInstream': 'Only video instream supported',
54+
'videoMissing': 'Bid request videoType property is missing - '
55+
};
56+
it('returns bid when respItem and LOG_ERROR_MESS is passed', function () {
57+
let response = getBidFromResponse(respItem, LOG_ERROR_MESS);
58+
expect(response).not.include.any.keys('emptyResponse', 'hasNoArrayOfBids', 'emptySeatbid');
59+
});
60+
});

0 commit comments

Comments
 (0)