• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

prebid / Prebid.js / 18168832719

01 Oct 2025 04:28PM UTC coverage: 96.244% (-0.001%) from 96.245%
18168832719

push

github

web-flow
Rimozione campi da adapter Prebid.js (#13956)

Co-authored-by: robin-crazygames <robin@crazygames.com>

51899 of 63496 branches covered (81.74%)

1 of 1 new or added line in 1 file covered. (100.0%)

9 existing lines in 5 files now uncovered.

198739 of 206494 relevant lines covered (96.24%)

125.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.37
/modules/atsAnalyticsAdapter.js
1
import { logError, logInfo } from '../src/utils.js';
1✔
2
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
3
import { EVENTS } from '../src/constants.js';
4
import adaptermanager from '../src/adapterManager.js';
5
import {ajax} from '../src/ajax.js';
6
import {getStorageManager} from '../src/storageManager.js';
7
import {getGlobal} from '../src/prebidGlobal.js';
8

9
import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js';
10
const MODULE_CODE = 'atsAnalytics';
1✔
11
export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE});
1✔
12

13
/**
14
 * Analytics adapter for - https://liveramp.com
15
 * Maintainer - prebid@liveramp.com
16
 */
17

18
const analyticsType = 'endpoint';
1✔
19

20
const preflightUrl = 'https://check.analytics.rlcdn.com/check/';
1✔
21
export const analyticsUrl = 'https://analytics.rlcdn.com';
1✔
22

23
let handlerRequest = [];
1✔
24
const handlerResponse = [];
1✔
25

26
const atsAnalyticsAdapterVersion = 3;
1✔
27

28
const browsersList = [
1✔
29
  /* Googlebot */
30
  {
31
    test: /googlebot/i,
32
    name: 'Googlebot'
33
  },
34

35
  /* Opera < 13.0 */
36
  {
37
    test: /opera/i,
38
    name: 'Opera',
39
  },
40

41
  /* Opera > 13.0 */
42
  {
43
    test: /opr\/|opios/i,
44
    name: 'Opera'
45
  },
46
  {
47
    test: /SamsungBrowser/i,
48
    name: 'Samsung Internet for Android',
49
  },
50
  {
51
    test: /Whale/i,
52
    name: 'NAVER Whale Browser',
53
  },
54
  {
55
    test: /MZBrowser/i,
56
    name: 'MZ Browser'
57
  },
58
  {
59
    test: /focus/i,
60
    name: 'Focus',
61
  },
62
  {
63
    test: /swing/i,
64
    name: 'Swing',
65
  },
66
  {
67
    test: /coast/i,
68
    name: 'Opera Coast',
69
  },
70
  {
71
    test: /opt\/\d+(?:.?_?\d+)+/i,
72
    name: 'Opera Touch',
73
  },
74
  {
75
    test: /yabrowser/i,
76
    name: 'Yandex Browser',
77
  },
78
  {
79
    test: /ucbrowser/i,
80
    name: 'UC Browser',
81
  },
82
  {
83
    test: /Maxthon|mxios/i,
84
    name: 'Maxthon',
85
  },
86
  {
87
    test: /epiphany/i,
88
    name: 'Epiphany',
89
  },
90
  {
91
    test: /puffin/i,
92
    name: 'Puffin',
93
  },
94
  {
95
    test: /sleipnir/i,
96
    name: 'Sleipnir',
97
  },
98
  {
99
    test: /k-meleon/i,
100
    name: 'K-Meleon',
101
  },
102
  {
103
    test: /micromessenger/i,
104
    name: 'WeChat',
105
  },
106
  {
107
    test: /qqbrowser/i,
108
    name: (/qqbrowserlite/i).test(window.navigator.userAgent) ? 'QQ Browser Lite' : 'QQ Browser',
1!
109
  },
110
  {
111
    test: /msie|trident/i,
112
    name: 'Internet Explorer',
113
  },
114
  {
115
    test: /\sedg\//i,
116
    name: 'Microsoft Edge',
117
  },
118
  {
119
    test: /edg([ea]|ios)/i,
120
    name: 'Microsoft Edge',
121
  },
122
  {
123
    test: /vivaldi/i,
124
    name: 'Vivaldi',
125
  },
126
  {
127
    test: /seamonkey/i,
128
    name: 'SeaMonkey',
129
  },
130
  {
131
    test: /sailfish/i,
132
    name: 'Sailfish',
133
  },
134
  {
135
    test: /silk/i,
136
    name: 'Amazon Silk',
137
  },
138
  {
139
    test: /phantom/i,
140
    name: 'PhantomJS',
141
  },
142
  {
143
    test: /slimerjs/i,
144
    name: 'SlimerJS',
145
  },
146
  {
147
    test: /blackberry|\bbb\d+/i,
148
    name: 'BlackBerry',
149
  },
150
  {
151
    test: /(web|hpw)[o0]s/i,
152
    name: 'WebOS Browser',
153
  },
154
  {
155
    test: /bada/i,
156
    name: 'Bada',
157
  },
158
  {
159
    test: /tizen/i,
160
    name: 'Tizen',
161
  },
162
  {
163
    test: /qupzilla/i,
164
    name: 'QupZilla',
165
  },
166
  {
167
    test: /firefox|iceweasel|fxios/i,
168
    name: 'Firefox',
169
  },
170
  {
171
    test: /electron/i,
172
    name: 'Electron',
173
  },
174
  {
175
    test: /MiuiBrowser/i,
176
    name: 'Miui',
177
  },
178
  {
179
    test: /chromium/i,
180
    name: 'Chromium',
181
  },
182
  {
183
    test: /chrome|crios|crmo/i,
184
    name: 'Chrome',
185
  },
186
  {
187
    test: /GSA/i,
188
    name: 'Google Search',
189
  },
190

191
  /* Android Browser */
192
  {
193
    test: /android/i,
194
    name: 'Android Browser',
195
  },
196

197
  /* PlayStation 4 */
198
  {
199
    test: /playstation 4/i,
200
    name: 'PlayStation 4',
201
  },
202

203
  /* Safari */
204
  {
205
    test: /safari|applewebkit/i,
206
    name: 'Safari',
207
  },
208
];
209

210
const listOfSupportedBrowsers = ['Safari', 'Chrome', 'Firefox', 'Microsoft Edge'];
1✔
211

212
function bidRequestedHandler(args) {
213
  const envelopeSourceCookieValue = storage.getCookie('_lr_env_src_ats');
1✔
214
  const envelopeSource = envelopeSourceCookieValue === 'true';
1✔
215
  let requests;
216
  requests = args.bids.map(function(bid) {
1✔
217
    return {
1✔
218
      envelope_source: envelopeSource,
219
      has_envelope: bid.userId ? !!bid.userId.idl_env : false,
1!
220
      bidder: bid.bidder,
221
      bid_id: bid.bidId,
222
      auction_id: args.auctionId,
223
      user_browser: parseBrowser(),
224
      user_platform: navigator.platform,
225
      auction_start: new Date(args.auctionStart).toJSON(),
226
      domain: window.location.hostname,
227
      pid: atsAnalyticsAdapter.context.pid,
228
      adapter_version: atsAnalyticsAdapterVersion,
229
      bid_won: false
230
    };
231
  });
232
  return requests;
1✔
233
}
234

235
function bidResponseHandler(args) {
236
  return {
1✔
237
    bid_id: args.requestId,
238
    response_time_stamp: new Date(args.responseTimestamp).toJSON(),
239
    currency: args.currency,
240
    cpm: args.cpm,
241
    net_revenue: args.netRevenue
242
  };
243
}
244

245
export function parseBrowser() {
246
  const ua = atsAnalyticsAdapter.getUserAgent();
7✔
247
  try {
7✔
248
    const result = browsersList.filter(function(obj) {
7✔
249
      return obj.test.test(ua);
294✔
250
    });
251
    const browserName = result && result.length ? result[0].name : '';
7✔
252
    return (listOfSupportedBrowsers.indexOf(browserName) >= 0) ? browserName : 'Unknown';
7✔
253
  } catch (err) {
254
    logError('ATS Analytics - Error while checking user browser!', err);
×
255
  }
256
}
257

258
function sendDataToAnalytic (events) {
259
  // send data to ats analytic endpoint
260
  try {
1✔
261
    const dataToSend = {'Data': events};
1✔
262
    const strJSON = JSON.stringify(dataToSend);
1✔
263
    logInfo('ATS Analytics - tried to send analytics data!');
1✔
264
    ajax(analyticsUrl, function () {
1✔
265
      logInfo('ATS Analytics - events sent successfully!');
×
266
    }, strJSON, {method: 'POST', contentType: 'application/json'});
267
  } catch (err) {
268
    logError('ATS Analytics - request encounter an error: ', err);
×
269
  }
270
}
271

272
// preflight request, to check did publisher have permission to send data to analytics endpoint
273
function preflightRequest (events) {
274
  logInfo('ATS Analytics - preflight request!');
×
275
  ajax(preflightUrl + atsAnalyticsAdapter.context.pid,
×
276
    {
277
      success: function (data) {
278
        const samplingRateObject = JSON.parse(data);
×
279
        logInfo('ATS Analytics - Sampling Rate: ', samplingRateObject);
×
280
        const samplingRate = samplingRateObject.samplingRate;
×
281
        atsAnalyticsAdapter.setSamplingCookie(samplingRate);
×
282
        const samplingRateNumber = Number(samplingRate);
×
283
        if (data && samplingRate && atsAnalyticsAdapter.shouldFireRequest(samplingRateNumber)) {
×
284
          logInfo('ATS Analytics - events to send: ', events);
×
285
          sendDataToAnalytic(events);
×
286
        }
287
      },
288
      error: function () {
289
        atsAnalyticsAdapter.setSamplingCookie(0);
×
290
        logInfo('ATS Analytics - Sampling Rate Request Error!');
×
291
      }
292
    }, undefined, {method: 'GET', crossOrigin: true});
293
}
294

295
const atsAnalyticsAdapter = Object.assign(adapter(
1✔
296
  {
297
    analyticsType
298
  }),
299
{
300
  track({eventType, args}) {
7✔
301
    if (typeof args !== 'undefined') {
7✔
302
      atsAnalyticsAdapter.callHandler(eventType, args);
7✔
303
    }
304
  }
305
});
306

307
// save the base class function
308
atsAnalyticsAdapter.originEnableAnalytics = atsAnalyticsAdapter.enableAnalytics;
1✔
309

310
// add check to not fire request every time, but instead to send 1/100
311
atsAnalyticsAdapter.shouldFireRequest = function (samplingRate) {
1✔
312
  if (samplingRate !== 0) {
4✔
313
    const shouldFireRequestValue = (Math.floor((Math.random() * 100 + 1)) === 100);
3✔
314
    logInfo('ATS Analytics - Should Fire Request: ', shouldFireRequestValue);
3✔
315
    return shouldFireRequestValue;
3✔
316
  } else {
317
    logInfo('ATS Analytics - Should Fire Request: ', false);
1✔
318
    return false;
1✔
319
  }
320
};
321

322
atsAnalyticsAdapter.getUserAgent = function () {
1✔
323
  return window.navigator.userAgent;
×
324
};
325

326
atsAnalyticsAdapter.setSamplingCookie = function (samplRate) {
1✔
327
  const now = new Date();
2✔
328
  now.setTime(now.getTime() + 604800000);
2✔
329
  storage.setCookie('_lr_sampling_rate', samplRate, now.toUTCString());
2✔
330
}
331

332
// override enableAnalytics so we can get access to the config passed in from the page
333
atsAnalyticsAdapter.enableAnalytics = function (config) {
1✔
334
  if (!config.options.pid) {
2✔
335
    logError('ATS Analytics - Publisher ID (pid) option is not defined. Analytics won\'t work');
1✔
336
    return;
1✔
337
  }
338
  atsAnalyticsAdapter.context = {
1✔
339
    events: [],
340
    pid: config.options.pid,
341
    bidWonTimeout: config.options.bidWonTimeout
342
  };
343
  logInfo('ATS Analytics - adapter enabled! ');
1✔
344
  atsAnalyticsAdapter.originEnableAnalytics(config);
1✔
345
};
346

347
atsAnalyticsAdapter.callHandler = function (evtype, args) {
1✔
348
  if (evtype === EVENTS.BID_REQUESTED) {
7✔
349
    handlerRequest = handlerRequest.concat(bidRequestedHandler(args));
1✔
350
  } else if (evtype === EVENTS.BID_RESPONSE) {
6✔
351
    handlerResponse.push(bidResponseHandler(args));
1✔
352
  }
353
  if (evtype === EVENTS.AUCTION_END) {
7✔
354
    const bidWonTimeout = atsAnalyticsAdapter.context.bidWonTimeout ? atsAnalyticsAdapter.context.bidWonTimeout : 2000;
1!
355
    let events = [];
1✔
356
    setTimeout(() => {
1✔
357
      const winningBids = getGlobal().getAllWinningBids();
1✔
358
      logInfo('ATS Analytics - winning bids: ', winningBids)
1✔
359
      // prepare format data for sending to analytics endpoint
360
      if (handlerRequest.length) {
1✔
361
        const wonEvent = {};
1✔
362
        if (handlerResponse.length) {
1!
363
          events = handlerRequest.filter(request => handlerResponse.filter(function (response) {
1✔
364
            if (request.bid_id === response.bid_id) {
1✔
365
              Object.assign(request, response);
1✔
366
            }
367
          }));
368
          if (winningBids.length) {
1✔
369
            events = events.filter(event => winningBids.filter(function (won) {
1✔
370
              wonEvent.bid_id = won.requestId;
1✔
371
              wonEvent.bid_won = true;
1✔
372
              if (event.bid_id === wonEvent.bid_id) {
1✔
373
                Object.assign(event, wonEvent);
1✔
374
              }
375
            }))
376
          }
377
        } else {
UNCOV
378
          events = handlerRequest;
×
379
        }
380
        // check should we send data to analytics or not, check first cookie value _lr_sampling_rate
381
        try {
1✔
382
          const samplingRateCookie = storage.getCookie('_lr_sampling_rate');
1✔
383
          if (!samplingRateCookie) {
1!
UNCOV
384
            preflightRequest(events);
×
385
          } else {
386
            if (atsAnalyticsAdapter.shouldFireRequest(parseInt(samplingRateCookie))) {
1✔
387
              logInfo('ATS Analytics - events to send: ', events);
1✔
388
              sendDataToAnalytic(events);
1✔
389
            }
390
          }
391
          // empty events array to not send duplicate events
392
          events = [];
1✔
393
        } catch (err) {
UNCOV
394
          logError('ATS Analytics - preflight request encounter an error: ', err);
×
395
        }
396
      }
397
    }, bidWonTimeout);
398
  }
399
}
400

401
adaptermanager.registerAnalyticsAdapter({
1✔
402
  adapter: atsAnalyticsAdapter,
403
  code: MODULE_CODE,
404
  gvlid: 97
405
});
406

407
export default atsAnalyticsAdapter;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc