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

prebid / Prebid.js / 19437775255

17 Nov 2025 05:00PM UTC coverage: 96.213% (-0.02%) from 96.231%
19437775255

push

github

web-flow
sevioBidAdapter_bugfix: Send all sizes instead of just maxSize (#14133)

* Send all sizes instead of just maxSize

* Added tests to cover modifs in the sizes that we are sending

53222 of 65234 branches covered (81.59%)

10 of 10 new or added lines in 2 files covered. (100.0%)

304 existing lines in 58 files now uncovered.

202715 of 210693 relevant lines covered (96.21%)

71.77 hits per line

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

87.95
/modules/validationFpdModule/index.ts
1
/**
1✔
2
 * This module sets default values and validates ortb2 first part data
3
 * @module modules/firstPartyData
4
 */
5
import {deepAccess, isEmpty, isNumber, logWarn} from '../../src/utils.js';
6
import {ORTB_MAP} from './config.js';
7
import {submodule} from '../../src/hook.js';
8
import {getCoreStorageManager} from '../../src/storageManager.js';
9

10
// TODO: do FPD modules need their own namespace?
11
const STORAGE = getCoreStorageManager('FPDValidation');
1✔
12
let optout;
13

14
/**
15
 * Check if data passed is empty
16
 * @param {*} data to test against
17
 * @returns {Boolean} is data empty
18
 */
19
function isEmptyData(data) {
20
  let check = true;
209✔
21

22
  if (typeof data === 'object' && !isEmpty(data)) {
209✔
23
    check = false;
92✔
24
  } else if (typeof data !== 'object' && (isNumber(data) || data)) {
117✔
25
    check = false;
108✔
26
  }
27

28
  return check;
209✔
29
}
30

31
/**
32
 * Check if required keys exist in data object
33
 * @param {Object} obj data object
34
 * @param {Array} required array of required keys
35
 * @param {String} parent object path (for printing warning)
36
 * @param {Number} i index of object value in the data array (for printing warning)
37
 * @returns {Boolean} is requirements fulfilled
38
 */
39
function getRequiredData(obj, required, parent, i) {
40
  let check = true;
67✔
41

42
  required.forEach(key => {
67✔
43
    if (!obj[key] || isEmptyData(obj[key])) {
100✔
44
      check = false;
9✔
45
      logWarn(`Filtered ${parent}[] value at index ${i} in ortb2 data: missing required property ${key}`);
9✔
46
    }
47
  });
48

49
  return check;
67✔
50
}
51

52
/**
53
 * Check if data type is valid
54
 * @param {*} data value to test against
55
 * @param {Object} mapping object containing type definition and if should be array bool
56
 * @returns {Boolean} is type fulfilled
57
 */
58
function typeValidation(data, mapping) {
59
  let check = false;
175✔
60

61
  switch (mapping.type) {
175✔
62
    case 'string':
63
      if (typeof data === 'string') check = true;
39✔
64
      break;
39✔
65
    case 'number':
66
      if (typeof data === 'number' && isFinite(data)) check = true;
16✔
67
      break;
16✔
68
    case 'object':
69
      if (typeof data === 'object') {
120✔
70
        if ((Array.isArray(data) && mapping.isArray) || (!Array.isArray(data) && !mapping.isArray)) check = true;
109✔
71
      }
72
      break;
120✔
73
  }
74

75
  return check;
175✔
76
}
77

78
/**
79
 * Validates ortb2 data arrays and filters out invalid data
80
 * @param {Array} arr ortb2 data array
81
 * @param {Object} child object defining child type and if array
82
 * @param {String} path config path of data array
83
 * @param {String} parent parent path for logging warnings
84
 * @returns {Array} validated/filtered data
85
 */
86
export function filterArrayData(arr, child, path, parent) {
87
  arr = arr.filter((index, i) => {
37✔
88
    const check = typeValidation(index, {type: child.type, isArray: child.isArray});
43✔
89

90
    if (check && Array.isArray(index) === Boolean(child.isArray)) {
43✔
91
      return true;
40✔
92
    }
93

94
    logWarn(`Filtered ${parent}[] value at index ${i} in ortb2 data: expected type ${child.type}`);
3✔
95
    return false;
3✔
96
  }).filter((index, i) => {
97
    let requiredCheck = true;
40✔
98
    const mapping = deepAccess(ORTB_MAP, path);
40✔
99

100
    if (mapping && mapping.required) requiredCheck = getRequiredData(index, mapping.required, parent, i);
40✔
101

102
    if (requiredCheck) return true;
40✔
103
    return false;
6✔
104
  }).reduce((result, value, i) => {
105
    let typeBool = false;
34✔
106
    const mapping = deepAccess(ORTB_MAP, path);
34✔
107

108
    switch (child.type) {
34✔
109
      case 'string':
110
        result.push(value);
3✔
111
        typeBool = true;
3✔
112
        break;
3✔
113
      case 'object':
114
        if (mapping && mapping.children) {
31!
115
          const validObject = validateFpd(value, path + '.children.', parent + '.');
31✔
116
          if (Object.keys(validObject).length) {
31✔
117
            const requiredCheck = getRequiredData(validObject, mapping.required, parent, i);
30✔
118

119
            if (requiredCheck) {
30✔
120
              result.push(validObject);
28✔
121
              typeBool = true;
28✔
122
            }
123
          }
124
        } else {
125
          result.push(value);
×
126
          typeBool = true;
×
127
        }
128
        break;
31✔
129
    }
130

131
    if (!typeBool) logWarn(`Filtered ${parent}[] value at index ${i}  in ortb2 data: expected type ${child.type}`);
34✔
132

133
    return result;
34✔
134
  }, []);
135

136
  return arr;
37✔
137
}
138

139
/**
140
 * Validates ortb2 object and filters out invalid data
141
 * @param {Object} fpd ortb2 object
142
 * @param {String} path config path of data array
143
 * @param {String} parent parent path for logging warnings
144
 * @returns {Object} validated/filtered data
145
 */
146
export function validateFpd(fpd, path = '', parent = '') {
79✔
147
  if (!fpd) return {};
79!
148

149
  // Filter out imp property if exists
150
  const validObject = Object.assign({}, Object.keys(fpd).filter(key => {
79✔
151
    const mapping = deepAccess(ORTB_MAP, path + key);
139✔
152

153
    if (!mapping || !mapping.invalid) return key;
139✔
154

155
    logWarn(`Filtered ${parent}${key} property in ortb2 data: invalid property`);
×
156
    return false;
×
157
  }).filter(key => {
158
    const mapping = deepAccess(ORTB_MAP, path + key);
139✔
159
    // let typeBool = false;
160
    const typeBool = (mapping) ? typeValidation(fpd[key], {type: mapping.type, isArray: mapping.isArray}) : true;
139✔
161

162
    if (typeBool || !mapping) return key;
139✔
163

164
    logWarn(`Filtered ${parent}${key} property in ortb2 data: expected type ${(mapping.isArray) ? 'array' : mapping.type}`);
14✔
165
    return false;
14✔
166
  }).reduce((result, key) => {
167
    const mapping = deepAccess(ORTB_MAP, path + key);
125✔
168
    let modified = {};
125✔
169

170
    if (mapping) {
125✔
171
      if (mapping.optoutApplies && optout) {
118!
172
        logWarn(`Filtered ${parent}${key} data: pubcid optout found`);
×
173
        return result;
×
174
      }
175

176
      modified = (mapping.type === 'object' && !mapping.isArray)
118✔
177
        ? validateFpd(fpd[key], path + key + '.children.', parent + key + '.')
178
        : (mapping.isArray && mapping.childType)
188✔
179
            ? filterArrayData(fpd[key], { type: mapping.childType, isArray: mapping.childisArray }, path + key, parent + key) : fpd[key];
180

181
      // Check if modified data has data and return
182
      (!isEmptyData(modified)) ? result[key] = modified
118✔
183
        : logWarn(`Filtered ${parent}${key} property in ortb2 data: empty data found`);
184
    } else {
185
      result[key] = fpd[key];
7✔
186
    }
187

188
    return result;
125✔
189
  }, {}));
190

191
  // Return validated data
192
  return validObject;
79✔
193
}
194

195
/**
196
 * Run validation on global and bidder config data for ortb2
197
 * @param {Object} data global and bidder config data
198
 * @returns {Object} validated data
199
 */
200
function runValidations(data) {
UNCOV
201
  return {
×
202
    global: validateFpd(data.global),
UNCOV
203
    bidder: Object.fromEntries(Object.entries(data.bidder).map(([bidder, conf]) => [bidder, validateFpd(conf)]))
×
204
  }
205
}
206

207
declare module '../../src/fpd/enrichment' {
208
  interface FirstPartyDataConfig {
209
    skipValidations?: boolean;
210
  }
211
}
212

213
/**
214
 * Sets default values to ortb2 if exists and adds currency and ortb2 setConfig callbacks on init
215
 * @param {Object} fpdConf configuration object
216
 * @param {Object} data ortb2 data
217
 * @returns {Object} processed data
218
 */
219
export function processFpd(fpdConf, data) {
220
  // Checks for existsnece of pubcid optout cookie/storage
221
  // if exists, filters user data out
UNCOV
222
  optout = (STORAGE.cookiesAreEnabled() && STORAGE.getCookie('_pubcid_optout')) ||
×
223
    (STORAGE.hasLocalStorage() && STORAGE.getDataFromLocalStorage('_pubcid_optout'));
224

UNCOV
225
  return (!fpdConf.skipValidations) ? runValidations(data) : data;
×
226
}
227

228
/** @type {{name: string, queue: number, processFpd: function}} */
229
export const validationSubmodule = {
1✔
230
  name: 'validation',
231
  queue: 1,
232
  processFpd
233
}
234

235
submodule('firstPartyData', validationSubmodule);
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