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

prebid / Prebid.js / 17551159456

08 Sep 2025 12:42PM UTC coverage: 96.247% (-0.006%) from 96.253%
17551159456

push

github

web-flow
fix double invoke (#13856)

39727 of 48861 branches covered (81.31%)

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

172 existing lines in 29 files now uncovered.

197550 of 205253 relevant lines covered (96.25%)

124.84 hits per line

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

99.5
/test/spec/modules/illuminBidAdapter_spec.js
1
import {expect} from 'chai';
2
import {
3
  spec as adapter,
4
  createDomain,
5
  storage
6
} from 'modules/illuminBidAdapter.js';
7
import * as utils from 'src/utils.js';
8
import {version} from 'package.json';
9
import {useFakeTimers} from 'sinon';
10
import {BANNER, VIDEO} from '../../../src/mediaTypes.js';
11
import {config} from '../../../src/config.js';
12
import {
13
  hashCode,
14
  extractPID,
15
  extractCID,
16
  extractSubDomain,
17
  getStorageItem,
18
  setStorageItem,
19
  tryParseJSON,
20
  getUniqueDealId,
21
} from '../../../libraries/vidazooUtils/bidderUtils.js';
22
import {getGlobal} from '../../../src/prebidGlobal.js';
23

24
export const TEST_ID_SYSTEMS = ['criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'pubcid', 'tdid', 'pubProvidedId'];
1✔
25

26
const SUB_DOMAIN = 'exchange';
1✔
27

28
const BID = {
1✔
29
  'bidId': '2d52001cabd527',
30
  'adUnitCode': 'div-gpt-ad-12345-0',
31
  'params': {
32
    'subDomain': SUB_DOMAIN,
33
    'cId': '59db6b3b4ffaa70004f45cdc',
34
    'pId': '59ac17c192832d0011283fe3',
35
    'bidFloor': 0.1,
36
    'ext': {
37
      'param1': 'loremipsum',
38
      'param2': 'dolorsitamet'
39
    }
40
  },
41
  'placementCode': 'div-gpt-ad-1460505748561-0',
42
  'sizes': [[300, 250], [300, 600]],
43
  'bidderRequestId': '1fdb5ff1b6eaa7',
44
  'bidRequestsCount': 4,
45
  'bidderRequestsCount': 3,
46
  'bidderWinsCount': 1,
47
  'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a',
48
  'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc',
49
  'mediaTypes': [BANNER],
50
  'ortb2Imp': {
51
    'ext': {
52
      'gpid': '0123456789',
53
      'tid': 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf'
54
    }
55
  }
56
};
57

58
const VIDEO_BID = {
1✔
59
  'bidId': '2d52001cabd527',
60
  'adUnitCode': '63550ad1ff6642d368cba59dh5884270560',
61
  'bidderRequestId': '12a8ae9ada9c13',
62
  'bidRequestsCount': 4,
63
  'bidderRequestsCount': 3,
64
  'bidderWinsCount': 1,
65
  'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc',
66
  'params': {
67
    'subDomain': SUB_DOMAIN,
68
    'cId': '635509f7ff6642d368cb9837',
69
    'pId': '59ac17c192832d0011283fe3',
70
    'bidFloor': 0.1
71
  },
72
  'sizes': [[545, 307]],
73
  'mediaTypes': {
74
    'video': {
75
      'playerSize': [[545, 307]],
76
      'context': 'instream',
77
      'mimes': [
78
        'video/mp4',
79
        'application/javascript'
80
      ],
81
      'protocols': [2, 3, 5, 6],
82
      'maxduration': 60,
83
      'minduration': 0,
84
      'startdelay': 0,
85
      'linearity': 1,
86
      'api': [2],
87
      'placement': 1
88
    }
89
  },
90
  'ortb2Imp': {
91
    'ext': {
92
      'gpid': '0123456789',
93
      'tid': '56e184c6-bde9-497b-b9b9-cf47a61381ee'
94
    }
95
  }
96
}
97

98
const ORTB2_DEVICE = {
1✔
99
  sua: {
100
    'source': 2,
101
    'platform': {
102
      'brand': 'Android',
103
      'version': ['8', '0', '0']
104
    },
105
    'browsers': [
106
      {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']},
107
      {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']},
108
      {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']}
109
    ],
110
    'mobile': 1,
111
    'model': 'SM-G955U',
112
    'bitness': '64',
113
    'architecture': ''
114
  },
115
  w: 980,
116
  h: 1720,
117
  dnt: 0,
118
  ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/125.0.6422.80 Mobile/15E148 Safari/604.1',
119
  language: 'en',
120
  devicetype: 1,
121
  make: 'Apple',
122
  model: 'iPhone 12 Pro Max',
123
  os: 'iOS',
124
  osv: '17.4',
125
  ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'},
126
};
127

128
const BIDDER_REQUEST = {
1✔
129
  'gdprConsent': {
130
    'consentString': 'consent_string',
131
    'gdprApplies': true
132
  },
133
  'gppString': 'gpp_string',
134
  'gppSid': [7],
135
  'uspConsent': 'consent_string',
136
  'refererInfo': {
137
    'page': 'https://www.greatsite.com',
138
    'ref': 'https://www.somereferrer.com'
139
  },
140
  'ortb2': {
141
    'site': {
142
      'content': {
143
        'language': 'en'
144
      }
145
    },
146
    'regs': {
147
      'gpp': 'gpp_string',
148
      'gpp_sid': [7],
149
      'coppa': 0
150
    },
151
    'device': ORTB2_DEVICE,
152
  }
153
};
154

155
const SERVER_RESPONSE = {
1✔
156
  body: {
157
    cid: 'testcid123',
158
    results: [{
159
      'ad': '<iframe>console.log("hello world")</iframe>',
160
      'price': 0.8,
161
      'creativeId': '12610997325162499419',
162
      'exp': 30,
163
      'width': 300,
164
      'height': 250,
165
      'advertiserDomains': ['securepubads.g.doubleclick.net'],
166
      'cookies': [{
167
        'src': 'https://sync.com',
168
        'type': 'iframe'
169
      }, {
170
        'src': 'https://sync.com',
171
        'type': 'img'
172
      }]
173
    }]
174
  }
175
};
176

177
const VIDEO_SERVER_RESPONSE = {
1✔
178
  body: {
179
    'cid': '635509f7ff6642d368cb9837',
180
    'results': [{
181
      'ad': '<VAST version=\"3.0\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"></VAST>',
182
      'advertiserDomains': ['illumin.com'],
183
      'exp': 60,
184
      'width': 545,
185
      'height': 307,
186
      'mediaType': 'video',
187
      'creativeId': '12610997325162499419',
188
      'price': 2,
189
      'cookies': []
190
    }]
191
  }
192
};
193

194
const ORTB2_OBJ = {
1✔
195
  "device": ORTB2_DEVICE,
196
  "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]},
197
  "site": {"content": {"language": "en"}
198
  }
199
};
200

201
const REQUEST = {
1✔
202
  data: {
203
    width: 300,
204
    height: 250,
205
    bidId: '2d52001cabd527'
206
  }
207
};
208

209
function getTopWindowQueryParams() {
210
  try {
2✔
211
    const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true});
2✔
212
    return parsedUrl.search;
2✔
213
  } catch (e) {
UNCOV
214
    return '';
×
215
  }
216
}
217

218
describe('IlluminBidAdapter', function () {
1✔
219
  before(() => config.resetConfig());
1✔
220
  after(() => config.resetConfig());
1✔
221

222
  describe('validtae spec', function () {
1✔
223
    it('exists and is a function', function () {
1✔
224
      expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function');
1✔
225
    });
226

227
    it('exists and is a function', function () {
1✔
228
      expect(adapter.buildRequests).to.exist.and.to.be.a('function');
1✔
229
    });
230

231
    it('exists and is a function', function () {
1✔
232
      expect(adapter.interpretResponse).to.exist.and.to.be.a('function');
1✔
233
    });
234

235
    it('exists and is a function', function () {
1✔
236
      expect(adapter.getUserSyncs).to.exist.and.to.be.a('function');
1✔
237
    });
238

239
    it('exists and is a string', function () {
1✔
240
      expect(adapter.code).to.exist.and.to.be.a('string');
1✔
241
    });
242

243
    it('exists and contains media types', function () {
1✔
244
      expect(adapter.supportedMediaTypes).to.exist.and.to.be.an('array').with.length(2);
1✔
245
      expect(adapter.supportedMediaTypes).to.contain.members([BANNER, VIDEO]);
1✔
246
    });
247
  });
248

249
  describe('validate bid requests', function () {
1✔
250
    it('should require cId', function () {
1✔
251
      const isValid = adapter.isBidRequestValid({
1✔
252
        params: {
253
          pId: 'pid'
254
        }
255
      });
256
      expect(isValid).to.be.false;
1✔
257
    });
258

259
    it('should require pId', function () {
1✔
260
      const isValid = adapter.isBidRequestValid({
1✔
261
        params: {
262
          cId: 'cid'
263
        }
264
      });
265
      expect(isValid).to.be.false;
1✔
266
    });
267

268
    it('should validate correctly', function () {
1✔
269
      const isValid = adapter.isBidRequestValid({
1✔
270
        params: {
271
          cId: 'cid',
272
          pId: 'pid'
273
        }
274
      });
275
      expect(isValid).to.be.true;
1✔
276
    });
277
  });
278

279
  describe('build requests', function () {
1✔
280
    let sandbox;
281
    before(function () {
1✔
282
      getGlobal().bidderSettings = {
1✔
283
        illumin: {
284
          storageAllowed: true
285
        }
286
      };
287
      sandbox = sinon.createSandbox();
1✔
288
      sandbox.stub(Date, 'now').returns(1000);
1✔
289
    });
290

291
    it('should build video request', function () {
1✔
292
      const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page);
1✔
293
      config.setConfig({
1✔
294
        bidderTimeout: 3000,
295
        enableTIDs: true
296
      });
297
      const requests = adapter.buildRequests([VIDEO_BID], BIDDER_REQUEST);
1✔
298
      expect(requests).to.have.length(1);
1✔
299
      expect(requests[0]).to.deep.equal({
1✔
300
        method: 'POST',
301
        url: `${createDomain(SUB_DOMAIN)}/prebid/multi/635509f7ff6642d368cb9837`,
302
        data: {
303
          adUnitCode: '63550ad1ff6642d368cba59dh5884270560',
304
          bidFloor: 0.1,
305
          bidId: '2d52001cabd527',
306
          bidderVersion: adapter.version,
307
          bidderRequestId: '12a8ae9ada9c13',
308
          cb: 1000,
309
          gdpr: 1,
310
          gdprConsent: 'consent_string',
311
          usPrivacy: 'consent_string',
312
          gppString: 'gpp_string',
313
          gppSid: [7],
314
          transactionId: '56e184c6-bde9-497b-b9b9-cf47a61381ee',
315
          prebidVersion: version,
316
          bidRequestsCount: 4,
317
          bidderRequestsCount: 3,
318
          bidderWinsCount: 1,
319
          bidderTimeout: 3000,
320
          publisherId: '59ac17c192832d0011283fe3',
321
          url: 'https%3A%2F%2Fwww.greatsite.com',
322
          referrer: 'https://www.somereferrer.com',
323
          res: `${window.top.screen.width}x${window.top.screen.height}`,
324
          schain: VIDEO_BID.schain,
325
          sizes: ['545x307'],
326
          sua: {
327
            'source': 2,
328
            'platform': {
329
              'brand': 'Android',
330
              'version': ['8', '0', '0']
331
            },
332
            'browsers': [
333
              {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']},
334
              {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']},
335
              {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']}
336
            ],
337
            'mobile': 1,
338
            'model': 'SM-G955U',
339
            'bitness': '64',
340
            'architecture': ''
341
          },
342
          device: ORTB2_DEVICE,
343
          uniqueDealId: `${hashUrl}_${Date.now().toString()}`,
344
          uqs: getTopWindowQueryParams(),
345
          mediaTypes: {
346
            video: {
347
              api: [2],
348
              context: 'instream',
349
              linearity: 1,
350
              maxduration: 60,
351
              mimes: [
352
                'video/mp4',
353
                'application/javascript'
354
              ],
355
              minduration: 0,
356
              placement: 1,
357
              playerSize: [[545, 307]],
358
              protocols: [2, 3, 5, 6],
359
              startdelay: 0
360
            }
361
          },
362
          gpid: '0123456789',
363
          cat: [],
364
          contentData: [],
365
          contentLang: 'en',
366
          isStorageAllowed: true,
367
          pagecat: [],
368
          ortb2: ORTB2_OBJ,
369
          ortb2Imp: VIDEO_BID.ortb2Imp,
370
          userData: [],
371
          coppa: 0
372
        }
373
      });
374
    });
375

376
    it('should build banner request for each size', function () {
1✔
377
      const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page);
1✔
378
      config.setConfig({
1✔
379
        bidderTimeout: 3000,
380
        enableTIDs: true
381
      });
382
      const requests = adapter.buildRequests([BID], BIDDER_REQUEST);
1✔
383
      expect(requests).to.have.length(1);
1✔
384
      expect(requests[0]).to.deep.equal({
1✔
385
        method: 'POST',
386
        url: `${createDomain(SUB_DOMAIN)}/prebid/multi/59db6b3b4ffaa70004f45cdc`,
387
        data: {
388
          gdprConsent: 'consent_string',
389
          gdpr: 1,
390
          gppString: 'gpp_string',
391
          gppSid: [7],
392
          usPrivacy: 'consent_string',
393
          bidRequestsCount: 4,
394
          bidderRequestsCount: 3,
395
          bidderWinsCount: 1,
396
          bidderTimeout: 3000,
397
          bidderRequestId: '1fdb5ff1b6eaa7',
398
          transactionId: 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf',
399
          sizes: ['300x250', '300x600'],
400
          sua: {
401
            'source': 2,
402
            'platform': {
403
              'brand': 'Android',
404
              'version': ['8', '0', '0']
405
            },
406
            'browsers': [
407
              {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']},
408
              {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']},
409
              {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']}
410
            ],
411
            'mobile': 1,
412
            'model': 'SM-G955U',
413
            'bitness': '64',
414
            'architecture': ''
415
          },
416
          device: ORTB2_DEVICE,
417
          url: 'https%3A%2F%2Fwww.greatsite.com',
418
          referrer: 'https://www.somereferrer.com',
419
          cb: 1000,
420
          bidFloor: 0.1,
421
          bidId: '2d52001cabd527',
422
          adUnitCode: 'div-gpt-ad-12345-0',
423
          publisherId: '59ac17c192832d0011283fe3',
424
          uniqueDealId: `${hashUrl}_${Date.now().toString()}`,
425
          bidderVersion: adapter.version,
426
          prebidVersion: version,
427
          schain: BID.schain,
428
          res: `${window.top.screen.width}x${window.top.screen.height}`,
429
          mediaTypes: [BANNER],
430
          gpid: '0123456789',
431
          uqs: getTopWindowQueryParams(),
432
          'ext.param1': 'loremipsum',
433
          'ext.param2': 'dolorsitamet',
434
          cat: [],
435
          contentData: [],
436
          contentLang: 'en',
437
          isStorageAllowed: true,
438
          pagecat: [],
439
          ortb2: ORTB2_OBJ,
440
          ortb2Imp: BID.ortb2Imp,
441
          userData: [],
442
          coppa: 0
443
        }
444
      });
445
    });
446

447
    after(function () {
1✔
448
      getGlobal().bidderSettings = {};
1✔
449
      sandbox.restore();
1✔
450
    });
451
  });
452
  describe('getUserSyncs', function () {
1✔
453
    it('should have valid user sync with iframeEnabled', function () {
1✔
454
      const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]);
1✔
455

456
      expect(result).to.deep.equal([{
1✔
457
        type: 'iframe',
458
        url: 'https://sync.illumin.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0'
459
      }]);
460
    });
461

462
    it('should have valid user sync with cid on response', function () {
1✔
463
      const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]);
1✔
464
      expect(result).to.deep.equal([{
1✔
465
        type: 'iframe',
466
        url: 'https://sync.illumin.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0'
467
      }]);
468
    });
469

470
    it('should have valid user sync with pixelEnabled', function () {
1✔
471
      const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]);
1✔
472

473
      expect(result).to.deep.equal([{
1✔
474
        'url': 'https://sync.illumin.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0',
475
        'type': 'image'
476
      }]);
477
    })
478

479
    it('should have valid user sync with coppa on response', function () {
1✔
480
      config.setConfig({
1✔
481
        coppa: 1
482
      });
483
      const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]);
1✔
484
      expect(result).to.deep.equal([{
1✔
485
        type: 'iframe',
486
        url: 'https://sync.illumin.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1'
487
      }]);
488
    });
489
  });
490

491
  describe('interpret response', function () {
1✔
492
    it('should return empty array when there is no response', function () {
1✔
493
      const responses = adapter.interpretResponse(null);
1✔
494
      expect(responses).to.be.empty;
1✔
495
    });
496

497
    it('should return empty array when there is no ad', function () {
1✔
498
      const responses = adapter.interpretResponse({price: 1, ad: ''});
1✔
499
      expect(responses).to.be.empty;
1✔
500
    });
501

502
    it('should return empty array when there is no price', function () {
1✔
503
      const responses = adapter.interpretResponse({price: null, ad: 'great ad'});
1✔
504
      expect(responses).to.be.empty;
1✔
505
    });
506

507
    it('should return an array of interpreted banner responses', function () {
1✔
508
      const responses = adapter.interpretResponse(SERVER_RESPONSE, REQUEST);
1✔
509
      expect(responses).to.have.length(1);
1✔
510
      expect(responses[0]).to.deep.equal({
1✔
511
        requestId: '2d52001cabd527',
512
        cpm: 0.8,
513
        width: 300,
514
        height: 250,
515
        creativeId: '12610997325162499419',
516
        currency: 'USD',
517
        netRevenue: true,
518
        ttl: 30,
519
        ad: '<iframe>console.log("hello world")</iframe>',
520
        meta: {
521
          advertiserDomains: ['securepubads.g.doubleclick.net']
522
        }
523
      });
524
    });
525

526
    it('should get meta from response metaData', function () {
1✔
527
      const serverResponse = utils.deepClone(SERVER_RESPONSE);
1✔
528
      serverResponse.body.results[0].metaData = {
1✔
529
        advertiserDomains: ['illumin.com'],
530
        agencyName: 'Agency Name',
531
      };
532
      const responses = adapter.interpretResponse(serverResponse, REQUEST);
1✔
533
      expect(responses[0].meta).to.deep.equal({
1✔
534
        advertiserDomains: ['illumin.com'],
535
        agencyName: 'Agency Name'
536
      });
537
    });
538

539
    it('should return an array of interpreted video responses', function () {
1✔
540
      const responses = adapter.interpretResponse(VIDEO_SERVER_RESPONSE, REQUEST);
1✔
541
      expect(responses).to.have.length(1);
1✔
542
      expect(responses[0]).to.deep.equal({
1✔
543
        requestId: '2d52001cabd527',
544
        cpm: 2,
545
        width: 545,
546
        height: 307,
547
        mediaType: 'video',
548
        creativeId: '12610997325162499419',
549
        currency: 'USD',
550
        netRevenue: true,
551
        ttl: 60,
552
        vastXml: '<VAST version=\"3.0\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"></VAST>',
553
        meta: {
554
          advertiserDomains: ['illumin.com']
555
        }
556
      });
557
    });
558

559
    it('should take default TTL', function () {
1✔
560
      const serverResponse = utils.deepClone(SERVER_RESPONSE);
1✔
561
      delete serverResponse.body.results[0].exp;
1✔
562
      const responses = adapter.interpretResponse(serverResponse, REQUEST);
1✔
563
      expect(responses).to.have.length(1);
1✔
564
      expect(responses[0].ttl).to.equal(300);
1✔
565
    });
566
  });
567

568
  describe('user id system', function () {
1✔
569
    TEST_ID_SYSTEMS.forEach((idSystemProvider) => {
1✔
570
      const id = Date.now().toString();
8✔
571
      const bid = utils.deepClone(BID);
8✔
572

573
      const userId = (function () {
8✔
574
        switch (idSystemProvider) {
8✔
575
          case 'lipb':
576
            return {lipbid: id};
1✔
577
          case 'id5id':
578
            return {uid: id};
1✔
579
          default:
580
            return id;
6✔
581
        }
582
      })();
583

584
      bid.userId = {
8✔
585
        [idSystemProvider]: userId
586
      };
587

588
      it(`should include 'uid.${idSystemProvider}' in request params`, function () {
8✔
589
        const requests = adapter.buildRequests([bid], BIDDER_REQUEST);
8✔
590
        expect(requests[0].data[`uid.${idSystemProvider}`]).to.equal(id);
8✔
591
      });
592
    });
593
    // testing bid.userIdAsEids handling
594
    it("should include user ids from bid.userIdAsEids (length=1)", function() {
1✔
595
      const bid = utils.deepClone(BID);
1✔
596
      bid.userIdAsEids = [
1✔
597
        {
598
          "source": "audigent.com",
599
          "uids": [{"id": "fakeidi6j6dlc6e"}]
600
        }
601
      ]
602
      const requests = adapter.buildRequests([bid], BIDDER_REQUEST);
1✔
603
      expect(requests[0].data['uid.audigent.com']).to.equal("fakeidi6j6dlc6e");
1✔
604
    })
605
    it("should include user ids from bid.userIdAsEids (length=2)", function() {
1✔
606
      const bid = utils.deepClone(BID);
1✔
607
      bid.userIdAsEids = [
1✔
608
        {
609
          "source": "audigent.com",
610
          "uids": [{"id": "fakeidi6j6dlc6e"}]
611
        },
612
        {
613
          "source": "rwdcntrl.net",
614
          "uids": [{"id": "fakeid6f35197d5c", "atype": 1}]
615
        }
616
      ]
617
      const requests = adapter.buildRequests([bid], BIDDER_REQUEST);
1✔
618
      expect(requests[0].data['uid.audigent.com']).to.equal("fakeidi6j6dlc6e");
1✔
619
      expect(requests[0].data['uid.rwdcntrl.net']).to.equal("fakeid6f35197d5c");
1✔
620
    })
621
    // testing user.ext.eid handling
622
    it("should include user ids from user.ext.eid (length=1)", function() {
1✔
623
      const bid = utils.deepClone(BID);
1✔
624
      bid.user = {
1✔
625
        ext: {
626
          eids: [
627
            {
628
              "source": "pubcid.org",
629
              "uids": [{"id": "fakeid8888dlc6e"}]
630
            }
631
          ]
632
        }
633
      }
634
      const requests = adapter.buildRequests([bid], BIDDER_REQUEST);
1✔
635
      expect(requests[0].data['uid.pubcid.org']).to.equal("fakeid8888dlc6e");
1✔
636
    })
637
    it("should include user ids from user.ext.eid (length=2)", function() {
1✔
638
      const bid = utils.deepClone(BID);
1✔
639
      bid.user = {
1✔
640
        ext: {
641
          eids: [
642
            {
643
              "source": "pubcid.org",
644
              "uids": [{"id": "fakeid8888dlc6e"}]
645
            },
646
            {
647
              "source": "adserver.org",
648
              "uids": [{"id": "fakeid495ff1"}]
649
            }
650
          ]
651
        }
652
      }
653
      const requests = adapter.buildRequests([bid], BIDDER_REQUEST);
1✔
654
      expect(requests[0].data['uid.pubcid.org']).to.equal("fakeid8888dlc6e");
1✔
655
      expect(requests[0].data['uid.adserver.org']).to.equal("fakeid495ff1");
1✔
656
    })
657
  });
658

659
  describe('alternate param names extractors', function () {
1✔
660
    it('should return undefined when param not supported', function () {
1✔
661
      const cid = extractCID({'c_id': '1'});
1✔
662
      const pid = extractPID({'p_id': '1'});
1✔
663
      const subDomain = extractSubDomain({'sub_domain': 'prebid'});
1✔
664
      expect(cid).to.be.undefined;
1✔
665
      expect(pid).to.be.undefined;
1✔
666
      expect(subDomain).to.be.undefined;
1✔
667
    });
668

669
    it('should return value when param supported', function () {
1✔
670
      const cid = extractCID({'cId': '1'});
1✔
671
      const pid = extractPID({'pId': '2'});
1✔
672
      const subDomain = extractSubDomain({'subDomain': 'prebid'});
1✔
673
      expect(cid).to.be.equal('1');
1✔
674
      expect(pid).to.be.equal('2');
1✔
675
      expect(subDomain).to.be.equal('prebid');
1✔
676
    });
677
  });
678

679
  describe('unique deal id', function () {
1✔
680
    before(function () {
1✔
681
      getGlobal().bidderSettings = {
1✔
682
        illumin: {
683
          storageAllowed: true
684
        }
685
      };
686
    });
687
    after(function () {
1✔
688
      getGlobal().bidderSettings = {};
1✔
689
    });
690
    const key = 'myKey';
1✔
691
    let uniqueDealId;
692
    beforeEach(() => {
1✔
693
      uniqueDealId = getUniqueDealId(storage, key, 0);
2✔
694
    })
695

696
    it('should get current unique deal id', function (done) {
1✔
697
      // waiting some time so `now` will become past
698
      setTimeout(() => {
1✔
699
        const current = getUniqueDealId(storage, key);
1✔
700
        expect(current).to.be.equal(uniqueDealId);
1✔
701
        done();
1✔
702
      }, 200);
703
    });
704

705
    it('should get new unique deal id on expiration', function (done) {
1✔
706
      setTimeout(() => {
1✔
707
        const current = getUniqueDealId(storage, key, 100);
1✔
708
        expect(current).to.not.be.equal(uniqueDealId);
1✔
709
        done();
1✔
710
      }, 200)
711
    });
712
  });
713

714
  describe('storage utils', function () {
1✔
715
    before(function () {
1✔
716
      getGlobal().bidderSettings = {
1✔
717
        illumin: {
718
          storageAllowed: true
719
        }
720
      };
721
    });
722
    after(function () {
1✔
723
      getGlobal().bidderSettings = {};
1✔
724
    });
725
    it('should get value from storage with create param', function () {
1✔
726
      const now = Date.now();
1✔
727
      const clock = useFakeTimers({
1✔
728
        shouldAdvanceTime: true,
729
        now
730
      });
731
      setStorageItem(storage, 'myKey', 2020);
1✔
732
      const {value, created} = getStorageItem(storage, 'myKey');
1✔
733
      expect(created).to.be.equal(now);
1✔
734
      expect(value).to.be.equal(2020);
1✔
735
      expect(typeof value).to.be.equal('number');
1✔
736
      expect(typeof created).to.be.equal('number');
1✔
737
      clock.restore();
1✔
738
    });
739

740
    it('should get external stored value', function () {
1✔
741
      const value = 'superman'
1✔
742
      window.localStorage.setItem('myExternalKey', value);
1✔
743
      const item = getStorageItem(storage, 'myExternalKey');
1✔
744
      expect(item).to.be.equal(value);
1✔
745
    });
746

747
    it('should parse JSON value', function () {
1✔
748
      const data = JSON.stringify({event: 'send'});
1✔
749
      const {event} = tryParseJSON(data);
1✔
750
      expect(event).to.be.equal('send');
1✔
751
    });
752

753
    it('should get original value on parse fail', function () {
1✔
754
      const value = 21;
1✔
755
      const parsed = tryParseJSON(value);
1✔
756
      expect(typeof parsed).to.be.equal('number');
1✔
757
      expect(parsed).to.be.equal(value);
1✔
758
    });
759
  });
760
});
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