• 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

89.87
/modules/timeoutRtdProvider.js
1
import { submodule } from '../src/hook.js';
1✔
2
import * as ajax from '../src/ajax.js';
3
import { logInfo, deepAccess, logError } from '../src/utils.js';
4
import { getGlobal } from '../src/prebidGlobal.js';
5

6
/**
7
 * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule
8
 */
9

10
const SUBMODULE_NAME = 'timeout';
1✔
11

12
// this allows the stubbing of functions during testing
13
export const timeoutRtdFunctions = {
1✔
14
  getDeviceType,
15
  getConnectionSpeed,
16
  checkVideo,
17
  calculateTimeoutModifier,
18
  handleTimeoutIncrement
19
};
20

21
const entries = Object.entries || function(obj) {
1!
22
  const ownProps = Object.keys(obj);
×
23
  let i = ownProps.length;
×
NEW
24
  const resArray = new Array(i);
×
25
  while (i--) { resArray[i] = [ownProps[i], obj[ownProps[i]]]; }
×
26
  return resArray;
×
27
};
28

29
function getDeviceType() {
30
  const userAgent = window.navigator.userAgent.toLowerCase();
3✔
31
  if ((/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(userAgent))) {
3✔
32
    return 5; // tablet
1✔
33
  }
34
  if ((/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(userAgent))) {
2✔
35
    return 4; // mobile
1✔
36
  }
37
  return 2; // personal computer
1✔
38
}
39

40
function checkVideo(adUnits) {
41
  return adUnits.some((adUnit) => {
5✔
42
    return adUnit.mediaTypes && adUnit.mediaTypes.video;
6✔
43
  });
44
}
45

46
function getConnectionSpeed() {
47
  const connection = window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection || {}
11!
48
  const connectionType = connection.type || connection.effectiveType;
11✔
49

50
  switch (connectionType) {
11✔
51
    case 'slow-2g':
52
    case '2g':
53
      return 'slow';
2✔
54

55
    case '3g':
56
      return 'medium';
1✔
57

58
    case 'bluetooth':
59
    case 'cellular':
60
    case 'ethernet':
61
    case 'wifi':
62
    case 'wimax':
63
    case '4g':
64
      return 'fast';
6✔
65
  }
66

67
  return 'unknown';
2✔
68
}
69
/**
70
 * Calculate the time to be added to the timeout
71
 * @param {Array} adUnits
72
 * @param {Object} rules
73
 * @return {number}
74
 */
75
function calculateTimeoutModifier(adUnits, rules) {
76
  logInfo('Timeout rules', rules);
8✔
77
  let timeoutModifier = 0;
8✔
78
  let toAdd = 0;
8✔
79

80
  if (rules.includesVideo) {
8✔
81
    const hasVideo = timeoutRtdFunctions.checkVideo(adUnits);
3✔
82
    toAdd = rules.includesVideo[hasVideo] || 0;
3!
83
    logInfo(`Adding ${toAdd} to timeout for includesVideo ${hasVideo}`)
3✔
84
    timeoutModifier += toAdd;
3✔
85
  }
86

87
  if (rules.numAdUnits) {
8✔
88
    const numAdUnits = adUnits.length;
5✔
89
    if (rules.numAdUnits[numAdUnits]) {
5✔
90
      timeoutModifier += rules.numAdUnits[numAdUnits];
2✔
91
    } else {
92
      for (const [rangeStr, timeoutVal] of entries(rules.numAdUnits)) {
3✔
93
        const [lowerBound, upperBound] = rangeStr.split('-');
4✔
94
        if (parseInt(lowerBound) <= numAdUnits && numAdUnits <= parseInt(upperBound)) {
4✔
95
          logInfo(`Adding ${timeoutVal} to timeout for numAdUnits ${numAdUnits}`)
3✔
96
          timeoutModifier += timeoutVal;
3✔
97
          break;
3✔
98
        }
99
      }
100
    }
101
  }
102

103
  if (rules.deviceType) {
8✔
104
    const deviceType = timeoutRtdFunctions.getDeviceType();
2✔
105
    toAdd = rules.deviceType[deviceType] || 0;
2!
106
    logInfo(`Adding ${toAdd} to timeout for deviceType ${deviceType}`)
2✔
107
    timeoutModifier += toAdd;
2✔
108
  }
109

110
  if (rules.connectionSpeed) {
8✔
111
    const connectionSpeed = timeoutRtdFunctions.getConnectionSpeed();
2✔
112
    toAdd = rules.connectionSpeed[connectionSpeed] || 0;
2!
113
    logInfo(`Adding ${toAdd} to timeout for connectionSpeed ${connectionSpeed}`)
2✔
114
    timeoutModifier += toAdd;
2✔
115
  }
116

117
  logInfo('timeout Modifier calculated', timeoutModifier);
8✔
118
  return timeoutModifier;
8✔
119
}
120

121
/**
122
 *
123
 * @param {Object} reqBidsConfigObj
124
 * @param {function} callback
125
 * @param {Object} config
126
 * @param {Object} userConsent
127
 */
128
function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) {
129
  logInfo('Timeout rtd config', config);
4✔
130
  const timeoutUrl = deepAccess(config, 'params.endpoint.url');
4✔
131
  if (timeoutUrl) {
4✔
132
    logInfo('Timeout url', timeoutUrl);
2✔
133
    ajax.ajaxBuilder()(timeoutUrl, {
2✔
134
      success: function(response) {
135
        try {
1✔
136
          const rules = JSON.parse(response);
1✔
137
          timeoutRtdFunctions.handleTimeoutIncrement(reqBidsConfigObj, rules);
1✔
138
        } catch (e) {
139
          logError('Error parsing json response from timeout provider.')
×
140
        }
141
        callback();
1✔
142
      },
143
      error: function(errorStatus) {
144
        logError('Timeout request error!', errorStatus);
×
145
        callback();
×
146
      }
147
    });
148
  } else if (deepAccess(config, 'params.rules')) {
2✔
149
    timeoutRtdFunctions.handleTimeoutIncrement(reqBidsConfigObj, deepAccess(config, 'params.rules'));
1✔
150
    callback();
1✔
151
  } else {
152
    logInfo('No timeout endpoint or timeout rules found. Exiting timeout rtd module');
1✔
153
    callback();
1✔
154
  }
155
}
156

157
/**
158
 * Gets the timeout modifier, adds it to the bidder timeout, and sets it to reqBidsConfigObj
159
 * @param {Object} reqBidsConfigObj
160
 * @param {Object} rules
161
 */
162
function handleTimeoutIncrement(reqBidsConfigObj, rules) {
163
  const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits;
2!
164
  const timeoutModifier = timeoutRtdFunctions.calculateTimeoutModifier(adUnits, rules);
2✔
165
  const bidderTimeout = reqBidsConfigObj.timeout || getGlobal().getConfig('bidderTimeout');
2✔
166
  reqBidsConfigObj.timeout = bidderTimeout + timeoutModifier;
2✔
167
}
168

169
/** @type {RtdSubmodule} */
170
export const timeoutSubmodule = {
1✔
171
  /**
172
   * used to link submodule with realTimeData
173
   * @type {string}
174
   */
175
  name: SUBMODULE_NAME,
176
  init: () => true,
1✔
177
  getBidRequestData,
178
};
179

180
function registerSubModule() {
181
  submodule('realTimeData', timeoutSubmodule);
1✔
182
}
183

184
registerSubModule();
1✔
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