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

prebid / Prebid.js / 16197995703

10 Jul 2025 02:32PM UTC coverage: 96.232% (+0.003%) from 96.229%
16197995703

push

github

web-flow
Linting: remove exception (#13518)

* bump coveralls

* remove exceptions

* results

* eslint fix

* Update package-lock.json

* Update package-lock.json

* Core: remove codex comments and unused lint rule (#13520)

---------

Co-authored-by: Demetrio Girardi <dgirardi@prebid.org>

39174 of 48116 branches covered (81.42%)

9842 of 9975 new or added lines in 861 files covered. (98.67%)

15 existing lines in 8 files now uncovered.

192483 of 200020 relevant lines covered (96.23%)

88.4 hits per line

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

71.78
/modules/fintezaAnalyticsAdapter.js
1
import { parseUrl, logError } from '../src/utils.js';
1✔
2
import { ajax } from '../src/ajax.js';
3
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
4
import adapterManager from '../src/adapterManager.js';
5
import {getStorageManager} from '../src/storageManager.js';
6
import { EVENTS } from '../src/constants.js';
7
import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js';
8

9
const MODULE_CODE = 'finteza';
1✔
10
const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE});
1✔
11

12
const ANALYTICS_TYPE = 'endpoint';
1✔
13
const FINTEZA_HOST = 'https://content.mql5.com/tr';
1✔
14
const BID_REQUEST_TRACK = 'Bid Request %BIDDER%';
1✔
15
const BID_RESPONSE_PRICE_TRACK = 'Bid Response Price %BIDDER%';
1✔
16
const BID_RESPONSE_TIME_TRACK = 'Bid Response Time %BIDDER%';
1✔
17
const BID_TIMEOUT_TRACK = 'Bid Timeout %BIDDER%';
1✔
18
const BID_WON_TRACK = 'Bid Won %BIDDER%';
1✔
19

20
const FIRST_VISIT_DATE = '_fz_fvdt';
1✔
21
const SESSION_ID = '_fz_ssn';
1✔
22
const SESSION_DURATION = 30 * 60 * 1000;
1✔
23
const SESSION_RAND_PART = 9;
1✔
24
const TRACK_TIME_KEY = '_fz_tr';
1✔
25
const UNIQ_ID_KEY = '_fz_uniq';
1✔
26

27
function getPageInfo() {
28
  const pageInfo = {
4✔
29
    domain: window.location.hostname,
30
  }
31

32
  if (document.referrer) {
4✔
33
    pageInfo.referrerDomain = parseUrl(document.referrer).hostname;
4✔
34
  }
35

36
  return pageInfo;
4✔
37
}
38

39
function getUniqId() {
40
  let isUniqFromLS;
41
  let uniq = storage.getCookie(UNIQ_ID_KEY);
4✔
42
  if (!uniq) {
4!
43
    try {
×
44
      if (storage.hasLocalStorage()) {
×
45
        uniq = storage.getDataFromLocalStorage(UNIQ_ID_KEY) || '';
×
46
        isUniqFromLS = true;
×
47
      }
48
    } catch (b) {}
49
  }
50

51
  if (uniq && isNaN(uniq)) {
4!
52
    uniq = null;
×
53
  }
54

55
  if (uniq && isUniqFromLS) {
4!
NEW
56
    const expires = new Date();
×
57
    expires.setFullYear(expires.getFullYear() + 10);
×
58

59
    try {
×
60
      storage.setCookie(UNIQ_ID_KEY, uniq, expires.toUTCString());
×
61
    } catch (e) {}
62
  }
63

64
  return uniq;
4✔
65
}
66

67
function initFirstVisit() {
68
  let now;
69
  let visitDate;
70
  let cookies;
71

72
  try {
4✔
73
    // TODO: commented out because of rule violations
74
    cookies = {} // parseCookies(document.cookie);
4✔
75
  } catch (a) {
76
    cookies = {};
×
77
  }
78

79
  visitDate = cookies[ FIRST_VISIT_DATE ];
4✔
80

81
  if (!visitDate) {
4✔
82
    now = new Date();
4✔
83

84
    visitDate = parseInt(now.getTime() / 1000, 10);
4✔
85

86
    now.setFullYear(now.getFullYear() + 20);
4✔
87

88
    try {
4✔
89
      storage.setCookie(FIRST_VISIT_DATE, visitDate, now.toUTCString());
4✔
90
    } catch (e) {}
91
  }
92

93
  return visitDate;
4✔
94
}
95
// TODO: commented out because of rule violations
96
/*
97
function trim(string) {
98
  if (string.trim) {
99
    return string.trim();
100
  }
101
  return string.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
102
}
103

104
function parseCookies(cookie) {
105
  let values = {};
106
  let arr, item;
107
  let param, value;
108
  let i, j;
109

110
  if (!cookie || !storage.cookiesAreEnabled()) {
111
    return {};
112
  }
113

114
  arr = cookie.split(';');
115

116
  for (i = 0, j = arr.length; i < j; i++) {
117
    item = arr[ i ];
118
    if (!item) {
119
      continue;
120
    }
121

122
    param = item.split('=');
123
    if (param.length <= 1) {
124
      continue;
125
    }
126

127
    value = decodeURIComponent(param[0]);
128
    value = trim(value);
129

130
    values[value] = decodeURIComponent(param[1]);
131
  }
132

133
  return values;
134
}
135
*/
136

137
function getRandAsStr(digits) {
138
  let str = '';
4✔
139
  let rand = 0;
4✔
140
  let i;
141

142
  digits = digits || 4;
4!
143

144
  for (i = 0; i < digits; i++) {
4✔
145
    rand = (Math.random() * 10) >>> 0;
36✔
146
    str += '' + rand;
36✔
147
  }
148

149
  return str;
4✔
150
}
151

152
function getSessionBegin(session) {
153
  if (!session || (typeof session !== 'string')) {
×
154
    return 0;
×
155
  }
156

157
  const len = session.length;
×
158
  if (len && len <= SESSION_RAND_PART) {
×
159
    return 0;
×
160
  }
161

162
  const timestamp = session.substring(0, len - SESSION_RAND_PART);
×
163

164
  return parseInt(timestamp, 10);
×
165
}
166

167
function initSession() {
168
  const now = new Date();
4✔
169
  const expires = new Date(now.getTime() + SESSION_DURATION);
4✔
170
  const timestamp = Math.floor(now.getTime() / 1000);
4✔
171
  let begin = 0;
4✔
172
  let cookies;
173
  let sessionId;
174
  let sessionDuration;
175
  let isNew = false;
4✔
176

177
  try {
4✔
178
    // TODO: commented out because of rule violations
179
    cookies = {} // parseCookies(document.cookie);
4✔
180
  } catch (a) {
181
    cookies = {};
×
182
  }
183

184
  sessionId = cookies[ SESSION_ID ];
4✔
185

186
  if (!sessionId ||
4!
187
      !checkSessionByExpires() ||
188
      !checkSessionByReferer() ||
189
      !checkSessionByDay()) {
190
    sessionId = '' + timestamp + getRandAsStr(SESSION_RAND_PART); // lgtm [js/insecure-randomness]
4✔
191
    begin = timestamp;
4✔
192

193
    isNew = true;
4✔
194
  } else {
195
    begin = getSessionBegin(sessionId);
×
196
  }
197

198
  if (begin > 0) {
4!
199
    sessionDuration = Math.floor(timestamp - begin);
4✔
200
  } else {
201
    sessionDuration = -1;
×
202
  }
203

204
  try {
4✔
205
    storage.setCookie(SESSION_ID, sessionId, expires.toUTCString());
4✔
206
  } catch (e) {}
207

208
  return {
4✔
209
    isNew: isNew,
210
    id: sessionId,
211
    duration: sessionDuration
212
  };
213
}
214

215
function checkSessionByExpires() {
216
  const timestamp = getTrackRequestLastTime();
×
217
  const now = new Date().getTime();
×
218

219
  if (now > timestamp + SESSION_DURATION) {
×
220
    return false;
×
221
  }
222
  return true;
×
223
}
224

225
function checkSessionByReferer() {
226
  const referrer = fntzAnalyticsAdapter.context.pageInfo.referrerDomain;
×
227
  const domain = fntzAnalyticsAdapter.context.pageInfo.domain;
×
228

229
  return referrer === '' || domain === referrer;
×
230
}
231

232
function checkSessionByDay() {
233
  let last = getTrackRequestLastTime();
×
234
  if (last) {
×
235
    last = new Date(last);
×
236
    const now = new Date();
×
237

238
    return last.getUTCDate() === now.getUTCDate() &&
×
239
      last.getUTCMonth() === now.getUTCMonth() &&
240
      last.getUTCFullYear() === now.getUTCFullYear();
241
  }
242

243
  return false;
×
244
}
245

246
function saveTrackRequestTime() {
247
  const now = new Date().getTime();
5✔
248
  const expires = new Date(now + SESSION_DURATION);
5✔
249

250
  try {
5✔
251
    if (storage.hasLocalStorage()) {
5!
252
      storage.setDataInLocalStorage(TRACK_TIME_KEY, now.toString());
5✔
253
    } else {
254
      storage.setCookie(TRACK_TIME_KEY, now.toString(), expires.toUTCString());
×
255
    }
256
  } catch (a) {}
257
}
258

259
function getTrackRequestLastTime() {
260
  let cookie;
261

262
  try {
×
263
    if (storage.hasLocalStorage()) {
×
264
      return parseInt(
×
265
        storage.getDataFromLocalStorage(TRACK_TIME_KEY) || 0,
×
266
        10,
267
      );
268
    }
269

270
    // TODO: commented out because of rule violations
271
    cookie = {} // parseCookies(document.cookie);
×
272
    cookie = cookie[ TRACK_TIME_KEY ];
×
273
    if (cookie) {
×
274
      return parseInt(cookie, 10);
×
275
    }
276
  } catch (e) {}
277

278
  return 0;
×
279
}
280

281
function getAntiCacheParam() {
282
  const date = new Date();
5✔
283
  const rand = (Math.random() * 99999 + 1) >>> 0;
5✔
284

285
  return ([ date.getTime(), rand ].join(''));
5✔
286
}
287

288
function replaceBidder(str, bidder) {
289
  let _str = str;
5✔
290
  _str = _str.replace(/\%bidder\%/, bidder.toLowerCase());
5✔
291
  _str = _str.replace(/\%BIDDER\%/, bidder.toUpperCase());
5✔
292
  _str = _str.replace(/\%Bidder\%/, bidder.charAt(0).toUpperCase() + bidder.slice(1).toLowerCase());
5✔
293

294
  return _str;
5✔
295
}
296

297
function prepareBidRequestedParams(args) {
298
  return [{
1✔
299
    event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidRequestTrack, args.bidderCode)),
300
    ref: encodeURIComponent(window.location.href),
301
  }];
302
}
303

304
function prepareBidResponseParams(args) {
305
  return [{
1✔
306
    event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidResponsePriceTrack, args.bidderCode)),
307
    value: args.cpm,
308
    unit: 'usd'
309
  }, {
310
    event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidResponseTimeTrack, args.bidderCode)),
311
    value: args.timeToRespond,
312
    unit: 'ms'
313
  }];
314
}
315

316
function prepareBidWonParams(args) {
317
  return [{
1✔
318
    event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidWonTrack, args.bidderCode)),
319
    value: args.cpm,
320
    unit: 'usd'
321
  }];
322
}
323

324
function prepareBidTimeoutParams(args) {
325
  return args.map(function(bid) {
1✔
326
    return {
1✔
327
      event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidTimeoutTrack, bid.bidder)),
328
      value: bid.timeout,
329
      unit: 'ms'
330
    };
331
  })
332
}
333

334
function prepareTrackData(evtype, args) {
335
  let prepareParams = null;
5✔
336

337
  switch (evtype) {
5✔
338
    case EVENTS.BID_REQUESTED:
339
      prepareParams = prepareBidRequestedParams;
1✔
340
      break;
1✔
341
    case EVENTS.BID_RESPONSE:
342
      prepareParams = prepareBidResponseParams;
1✔
343
      break;
1✔
344
    case EVENTS.BID_WON:
345
      prepareParams = prepareBidWonParams;
1✔
346
      break;
1✔
347
    case EVENTS.BID_TIMEOUT:
348
      prepareParams = prepareBidTimeoutParams;
1✔
349
      break;
1✔
350
  }
351

352
  if (!prepareParams) { return null; }
5✔
353

354
  const data = prepareParams(args);
4✔
355

356
  if (!data) { return null; }
4!
357

358
  const session = initSession();
4✔
359

360
  return data.map(d => {
4✔
361
    const trackData = Object.assign(d, {
5✔
362
      id: fntzAnalyticsAdapter.context.id,
363
      ref: encodeURIComponent(window.location.href),
364
      title: encodeURIComponent(document.title),
365
      scr_res: fntzAnalyticsAdapter.context.screenResolution,
366
      fv_date: fntzAnalyticsAdapter.context.firstVisit,
367
      ac: getAntiCacheParam(),
368
    })
369

370
    if (fntzAnalyticsAdapter.context.uniqId) {
5✔
371
      trackData.fz_uniq = fntzAnalyticsAdapter.context.uniqId;
5✔
372
    }
373

374
    if (session.id) {
5✔
375
      trackData.ssn = session.id;
5✔
376
    }
377
    if (session.isNew) {
5✔
378
      session.isNew = false;
4✔
379
      trackData.ssn_start = 1;
4✔
380
    }
381
    trackData.ssn_dr = session.duration;
5✔
382

383
    return trackData;
5✔
384
  });
385
}
386

387
function sendTrackRequest(trackData) {
388
  try {
5✔
389
    ajax(
5✔
390
      fntzAnalyticsAdapter.context.host,
391
      null,
392
      trackData,
393
      {
394
        method: 'GET',
395
        withCredentials: true,
396
        contentType: 'application/x-www-form-urlencoded'
397
      },
398
    );
399
    saveTrackRequestTime();
5✔
400
  } catch (err) {
401
    logError('Error on send data: ', err);
×
402
  }
403
}
404

405
const fntzAnalyticsAdapter = Object.assign(
1✔
406
  adapter({
407
    FINTEZA_HOST,
408
    ANALYTICS_TYPE
409
  }),
410
  {
411
    track({ eventType, args }) {
5✔
412
      if (typeof args !== 'undefined') {
5✔
413
        const trackData = prepareTrackData(eventType, args);
5✔
414
        if (!trackData) { return; }
5✔
415

416
        trackData.forEach(sendTrackRequest);
4✔
417
      }
418
    }
419
  }
420
);
421

422
fntzAnalyticsAdapter.originEnableAnalytics = fntzAnalyticsAdapter.enableAnalytics;
1✔
423

424
fntzAnalyticsAdapter.enableAnalytics = function (config) {
1✔
425
  if (!config.options.id) {
4!
426
    logError('Client ID (id) option is not defined. Analytics won\'t work');
×
427
    return;
×
428
  }
429

430
  fntzAnalyticsAdapter.context = {
4✔
431
    host: config.options.host || FINTEZA_HOST,
8✔
432
    id: config.options.id,
433
    bidRequestTrack: config.options.bidRequestTrack || BID_REQUEST_TRACK,
4!
434
    bidResponsePriceTrack: config.options.bidResponsePriceTrack || BID_RESPONSE_PRICE_TRACK,
4!
435
    bidResponseTimeTrack: config.options.bidResponseTimeTrack || BID_RESPONSE_TIME_TRACK,
4!
436
    bidTimeoutTrack: config.options.bidTimeoutTrack || BID_TIMEOUT_TRACK,
4!
437
    bidWonTrack: config.options.bidWonTrack || BID_WON_TRACK,
4!
438
    firstVisit: initFirstVisit(),
439
    screenResolution: `${window.screen.width}x${window.screen.height}`,
440
    uniqId: getUniqId(),
441
    pageInfo: getPageInfo(),
442
  };
443

444
  fntzAnalyticsAdapter.originEnableAnalytics(config);
4✔
445
};
446

447
adapterManager.registerAnalyticsAdapter({
1✔
448
  adapter: fntzAnalyticsAdapter,
449
  code: MODULE_CODE,
450
});
451

452
export default fntzAnalyticsAdapter;
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