prebid.js 6.6.0 → 6.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/integrationExamples/gpt/amp/creative.html +11 -33
  2. package/modules/adbookpspBidAdapter.js +27 -10
  3. package/modules/adhashBidAdapter.js +3 -3
  4. package/modules/colossussspBidAdapter.js +12 -8
  5. package/modules/colossussspBidAdapter.md +15 -1
  6. package/modules/compassBidAdapter.js +1 -1
  7. package/modules/consumableBidAdapter.md +1 -1
  8. package/modules/gnetBidAdapter.js +3 -3
  9. package/modules/gnetBidAdapter.md +4 -4
  10. package/modules/gumgumBidAdapter.js +4 -4
  11. package/modules/jwplayerRtdProvider.js +71 -6
  12. package/modules/jwplayerRtdProvider.md +27 -11
  13. package/modules/kargoBidAdapter.js +2 -2
  14. package/modules/pilotxBidAdapter.js +147 -0
  15. package/modules/pilotxBidAdapter.md +50 -0
  16. package/modules/rtdModule/index.js +8 -10
  17. package/modules/rubiconAnalyticsAdapter.js +3 -2
  18. package/modules/seedingAllianceBidAdapter.js +3 -3
  19. package/modules/sharethroughBidAdapter.js +12 -17
  20. package/modules/synacormediaBidAdapter.js +31 -10
  21. package/modules/viewability.js +177 -0
  22. package/modules/viewability.md +87 -0
  23. package/package.json +1 -1
  24. package/src/secureCreatives.js +3 -2
  25. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  26. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  27. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  28. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  29. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  30. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  31. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  32. package/test/spec/modules/realTimeDataModule_spec.js +51 -2
  33. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +30 -0
  34. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  35. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  36. package/test/spec/modules/viewability_spec.js +280 -0
@@ -7,7 +7,8 @@ describe('ColossussspAdapter', function () {
7
7
  bidder: 'colossusssp',
8
8
  bidderRequestId: '145e1d6a7837c9',
9
9
  params: {
10
- placement_id: 0
10
+ placement_id: 0,
11
+ group_id: 0
11
12
  },
12
13
  placementCode: 'placementid_0',
13
14
  auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2',
@@ -60,6 +61,7 @@ describe('ColossussspAdapter', function () {
60
61
  });
61
62
  it('Should return false when placement_id is not a number', function () {
62
63
  bid.params.placement_id = 'aaa';
64
+ delete bid.params.group_id;
63
65
  expect(spec.isBidRequestValid(bid)).to.be.false;
64
66
  });
65
67
  });
@@ -95,9 +97,10 @@ describe('ColossussspAdapter', function () {
95
97
  let placements = data['placements'];
96
98
  for (let i = 0; i < placements.length; i++) {
97
99
  let placement = placements[i];
98
- expect(placement).to.have.all.keys('placementId', 'eids', 'bidId', 'traffic', 'sizes', 'schain', 'floor', 'gpid');
100
+ expect(placement).to.have.all.keys('placementId', 'groupId', 'eids', 'bidId', 'traffic', 'sizes', 'schain', 'floor', 'gpid');
99
101
  expect(placement.schain).to.be.an('object')
100
102
  expect(placement.placementId).to.be.a('number');
103
+ expect(placement.groupId).to.be.a('number');
101
104
  expect(placement.bidId).to.be.a('string');
102
105
  expect(placement.traffic).to.be.a('string');
103
106
  expect(placement.sizes).to.be.an('array');
@@ -8,7 +8,7 @@ import {
8
8
  newBidder
9
9
  } from 'src/adapters/bidderFactory.js';
10
10
 
11
- const ENDPOINT = 'https://adserver.gnetproject.com/prebid.php';
11
+ const ENDPOINT = 'https://service.gnetrtb.com/api/adrequest';
12
12
 
13
13
  describe('gnetAdapter', function () {
14
14
  const adapter = newBidder(spec);
@@ -23,7 +23,7 @@ describe('gnetAdapter', function () {
23
23
  let bid = {
24
24
  bidder: 'gnet',
25
25
  params: {
26
- websiteId: '4'
26
+ websiteId: '1', adunitId: '1'
27
27
  }
28
28
  };
29
29
 
@@ -43,7 +43,7 @@ describe('gnetAdapter', function () {
43
43
  const bidRequests = [{
44
44
  bidder: 'gnet',
45
45
  params: {
46
- websiteId: '4'
46
+ websiteId: '1', adunitId: '1'
47
47
  },
48
48
  adUnitCode: '/150790500/4_ZONA_IAB_300x250_5',
49
49
  sizes: [
@@ -57,7 +57,7 @@ describe('gnetAdapter', function () {
57
57
 
58
58
  const bidderRequest = {
59
59
  refererInfo: {
60
- referer: 'https://gnetproject.com/'
60
+ referer: 'https://gnetrtb.com'
61
61
  }
62
62
  };
63
63
 
@@ -66,13 +66,13 @@ describe('gnetAdapter', function () {
66
66
  expect(requests[0].url).to.equal(ENDPOINT);
67
67
  expect(requests[0].method).to.equal('POST');
68
68
  expect(requests[0].data).to.equal(JSON.stringify({
69
- 'referer': 'https://gnetproject.com/',
69
+ 'referer': 'https://gnetrtb.com',
70
70
  'adUnitCode': '/150790500/4_ZONA_IAB_300x250_5',
71
71
  'bidId': '2a19afd5173318',
72
72
  'transactionId': '894bdff6-61ec-4bec-a5a9-f36a5bfccef5',
73
73
  'sizes': ['300x250'],
74
74
  'params': {
75
- 'websiteId': '4'
75
+ 'websiteId': '1', 'adunitId': '1'
76
76
  }
77
77
  }));
78
78
  });
@@ -1,7 +1,8 @@
1
1
  import { fetchTargetingForMediaId, getVatFromCache, extractPublisherParams,
2
2
  formatTargetingResponse, getVatFromPlayer, enrichAdUnits, addTargetingToBid,
3
- fetchTargetingInformation, jwplayerSubmodule } from 'modules/jwplayerRtdProvider.js';
3
+ fetchTargetingInformation, jwplayerSubmodule, getContentId, getContentData } from 'modules/jwplayerRtdProvider.js';
4
4
  import { server } from 'test/mocks/xhr.js';
5
+ import {addOrtbSiteContent} from '../../../modules/jwplayerRtdProvider';
5
6
 
6
7
  describe('jwplayerRtdProvider', function() {
7
8
  const testIdForSuccess = 'test_id_for_success';
@@ -412,7 +413,7 @@ describe('jwplayerRtdProvider', function() {
412
413
  });
413
414
  });
414
415
 
415
- describe(' Extract Publisher Params', function () {
416
+ describe('Extract Publisher Params', function () {
416
417
  const config = { mediaID: 'test' };
417
418
 
418
419
  it('should exclude adUnits that do not support instream video and do not specify jwTargeting', function () {
@@ -480,6 +481,198 @@ describe('jwplayerRtdProvider', function() {
480
481
  })
481
482
  });
482
483
 
484
+ describe('Get content id', function() {
485
+ it('prefixes jw_ to the media id', function () {
486
+ const mediaId = 'mediaId';
487
+ const contentId = getContentId(mediaId);
488
+ expect(contentId).to.equal('jw_mediaId');
489
+ });
490
+
491
+ it('returns undefined when media id is empty', function () {
492
+ let contentId = getContentId();
493
+ expect(contentId).to.be.undefined;
494
+ contentId = getContentId('');
495
+ expect(contentId).to.be.undefined;
496
+ contentId = getContentId(null);
497
+ expect(contentId).to.be.undefined;
498
+ });
499
+ });
500
+
501
+ describe('Get Content Data', function () {
502
+ it('returns undefined when segments are empty', function () {
503
+ let data = getContentData(null);
504
+ expect(data).to.be.undefined;
505
+ data = getContentData(undefined);
506
+ expect(data).to.be.undefined;
507
+ data = getContentData([]);
508
+ expect(data).to.be.undefined;
509
+ });
510
+
511
+ it('returns proper format', function () {
512
+ const segment1 = 'segment1';
513
+ const segment2 = 'segment2';
514
+ const segment3 = 'segment3';
515
+ const data = getContentData([segment1, segment2, segment3]);
516
+ expect(data).to.have.property('name', 'jwplayer');
517
+ expect(data.ext).to.have.property('segtax', 502);
518
+ expect(data.segment[0]).to.deep.equal({ id: segment1, value: segment1 });
519
+ expect(data.segment[1]).to.deep.equal({ id: segment2, value: segment2 });
520
+ expect(data.segment[2]).to.deep.equal({ id: segment3, value: segment3 });
521
+ });
522
+ });
523
+
524
+ describe(' Add Ortb Site Content', function () {
525
+ it('should maintain object structure when id and data params are empty', function () {
526
+ const bid = {
527
+ ortb2: {
528
+ site: {
529
+ content: {
530
+ id: 'randomId'
531
+ },
532
+ random: {
533
+ random_sub: 'randomSub'
534
+ }
535
+ },
536
+ app: {
537
+ content: {
538
+ id: 'appId'
539
+ }
540
+ }
541
+ }
542
+ };
543
+ addOrtbSiteContent(bid);
544
+ expect(bid).to.have.nested.property('ortb2.site.content.id', 'randomId');
545
+ expect(bid).to.have.nested.property('ortb2.site.random.random_sub', 'randomSub');
546
+ expect(bid).to.have.nested.property('ortb2.app.content.id', 'appId');
547
+ });
548
+
549
+ it('should create a structure compliant with the oRTB 2 spec', function() {
550
+ const bid = {};
551
+ const expectedId = 'expectedId';
552
+ const expectedData = { datum: 'datum' };
553
+ addOrtbSiteContent(bid, expectedId, expectedData);
554
+ expect(bid).to.have.nested.property('ortb2.site.content.id', expectedId);
555
+ expect(bid).to.have.nested.property('ortb2.site.content.data');
556
+ expect(bid.ortb2.site.content.data[0]).to.be.deep.equal(expectedData);
557
+ });
558
+
559
+ it('should respect existing structure when adding adding fields', function () {
560
+ const bid = {
561
+ ortb2: {
562
+ site: {
563
+ content: {
564
+ id: 'oldId'
565
+ },
566
+ random: {
567
+ random_sub: 'randomSub'
568
+ }
569
+ },
570
+ app: {
571
+ content: {
572
+ id: 'appId'
573
+ }
574
+ }
575
+ }
576
+ };
577
+
578
+ const expectedId = 'expectedId';
579
+ const expectedData = { datum: 'datum' };
580
+ addOrtbSiteContent(bid, expectedId, expectedData);
581
+ expect(bid).to.have.nested.property('ortb2.site.random.random_sub', 'randomSub');
582
+ expect(bid).to.have.nested.property('ortb2.app.content.id', 'appId');
583
+ expect(bid).to.have.nested.property('ortb2.site.content.id', expectedId);
584
+ expect(bid).to.have.nested.property('ortb2.site.content.data');
585
+ expect(bid.ortb2.site.content.data[0]).to.be.deep.equal(expectedData);
586
+ });
587
+
588
+ it('should set content id', function () {
589
+ const bid = {};
590
+ const expectedId = 'expectedId';
591
+ addOrtbSiteContent(bid, expectedId);
592
+ expect(bid).to.have.nested.property('ortb2.site.content.id', expectedId);
593
+ });
594
+
595
+ it('should override content id', function () {
596
+ const bid = {
597
+ ortb2: {
598
+ site: {
599
+ content: {
600
+ id: 'oldId'
601
+ }
602
+ }
603
+ }
604
+ };
605
+
606
+ const expectedId = 'expectedId';
607
+ addOrtbSiteContent(bid, expectedId);
608
+ expect(bid).to.have.nested.property('ortb2.site.content.id', expectedId);
609
+ });
610
+
611
+ it('should keep previous content id when not set', function () {
612
+ const previousId = 'oldId';
613
+ const bid = {
614
+ ortb2: {
615
+ site: {
616
+ content: {
617
+ id: previousId,
618
+ data: [{ datum: 'first_datum' }]
619
+ }
620
+ }
621
+ }
622
+ };
623
+
624
+ addOrtbSiteContent(bid, null, { datum: 'new_datum' });
625
+ expect(bid).to.have.nested.property('ortb2.site.content.id', previousId);
626
+ });
627
+
628
+ it('should set content data', function () {
629
+ const bid = {};
630
+ const expectedData = { datum: 'datum' };
631
+ addOrtbSiteContent(bid, null, expectedData);
632
+ expect(bid).to.have.nested.property('ortb2.site.content.data');
633
+ expect(bid.ortb2.site.content.data).to.have.length(1);
634
+ expect(bid.ortb2.site.content.data[0]).to.be.deep.equal(expectedData);
635
+ });
636
+
637
+ it('should append content data', function () {
638
+ const bid = {
639
+ ortb2: {
640
+ site: {
641
+ content: {
642
+ data: [{ datum: 'first_datum' }]
643
+ }
644
+ }
645
+ }
646
+ };
647
+
648
+ const expectedData = { datum: 'datum' };
649
+ addOrtbSiteContent(bid, null, expectedData);
650
+ expect(bid).to.have.nested.property('ortb2.site.content.data');
651
+ expect(bid.ortb2.site.content.data).to.have.length(2);
652
+ expect(bid.ortb2.site.content.data.pop()).to.be.deep.equal(expectedData);
653
+ });
654
+
655
+ it('should keep previous data when not set', function () {
656
+ const expectedId = 'expectedId';
657
+ const expectedData = { datum: 'first_datum' };
658
+ const bid = {
659
+ ortb2: {
660
+ site: {
661
+ content: {
662
+ data: [expectedData]
663
+ }
664
+ }
665
+ }
666
+ };
667
+
668
+ addOrtbSiteContent(bid, expectedId);
669
+ expect(bid).to.have.nested.property('ortb2.site.content.data');
670
+ expect(bid.ortb2.site.content.data).to.have.length(1);
671
+ expect(bid.ortb2.site.content.data[0]).to.be.deep.equal(expectedData);
672
+ expect(bid).to.have.nested.property('ortb2.site.content.id', expectedId);
673
+ });
674
+ });
675
+
483
676
  describe('Add Targeting to Bid', function () {
484
677
  const targeting = {foo: 'bar'};
485
678
 
@@ -484,7 +484,7 @@ describe('kargo adapter tests', function () {
484
484
  height: 250,
485
485
  targetingCustom: 'dmpmptest1234',
486
486
  metadata: {
487
- landingPageDomain: 'https://foobar.com'
487
+ landingPageDomain: ['https://foobar.com']
488
488
  }
489
489
  },
490
490
  3: {
@@ -0,0 +1,244 @@
1
+ // import or require modules necessary for the test, e.g.:
2
+ import { expect } from 'chai'; // may prefer 'assert' in place of 'expect'
3
+ import { spec } from '../../../modules/pilotxBidAdapter.js';
4
+
5
+ describe('pilotxAdapter', function () {
6
+ describe('isBidRequestValid', function () {
7
+ let banner;
8
+ beforeEach(function () {
9
+ banner = {
10
+ bidder: 'pilotx',
11
+ adUnitCode: 'adunit-test',
12
+ mediaTypes: { banner: {} },
13
+ sizes: [[300, 250], [468, 60]],
14
+ bidId: '2de8c82e30665a',
15
+ params: {
16
+ placementId: '1'
17
+ }
18
+ };
19
+ });
20
+
21
+ it('should return false if sizes is empty', function () {
22
+ banner.sizes = []
23
+ expect(spec.isBidRequestValid(banner)).to.equal(false);
24
+ });
25
+ it('should return true if all is valid/ is not empty', function () {
26
+ expect(spec.isBidRequestValid(banner)).to.equal(true);
27
+ });
28
+ it('should return false if there is no placement id found', function () {
29
+ banner.params = {}
30
+ expect(spec.isBidRequestValid(banner)).to.equal(false);
31
+ });
32
+ it('should return false if sizes is empty', function () {
33
+ banner.sizes = []
34
+ expect(spec.isBidRequestValid(banner)).to.equal(false);
35
+ });
36
+ it('should return false for no size and empty params', function() {
37
+ const emptySizes = {
38
+ bidder: 'pilotx',
39
+ adUnitCode: 'adunit-test',
40
+ mediaTypes: { banner: {} },
41
+ bidId: '2de8c82e30665a',
42
+ params: {
43
+ placementId: '1',
44
+ sizes: []
45
+ }
46
+ };
47
+ expect(spec.isBidRequestValid(emptySizes)).to.equal(false);
48
+ })
49
+ it('should return true for no size and valid size params', function() {
50
+ const emptySizes = {
51
+ bidder: 'pilotx',
52
+ adUnitCode: 'adunit-test',
53
+ mediaTypes: { banner: {} },
54
+ bidId: '2de8c82e30665a',
55
+ params: {
56
+ placementId: '1',
57
+ sizes: [[300, 250], [468, 60]]
58
+ }
59
+ };
60
+ expect(spec.isBidRequestValid(emptySizes)).to.equal(true);
61
+ })
62
+ it('should return false for no size items', function() {
63
+ const emptySizes = {
64
+ bidder: 'pilotx',
65
+ adUnitCode: 'adunit-test',
66
+ mediaTypes: { banner: {} },
67
+ bidId: '2de8c82e30665a',
68
+ params: {
69
+ placementId: '1'
70
+ }
71
+ };
72
+ expect(spec.isBidRequestValid(emptySizes)).to.equal(false);
73
+ })
74
+ });
75
+
76
+ describe('buildRequests', function () {
77
+ const mockRequest = { refererInfo: {} };
78
+ const mockRequestGDPR = {
79
+ refererInfo: {},
80
+ gdprConsent: {
81
+ consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==',
82
+ gdprApplies: true
83
+ }
84
+
85
+ }
86
+ const mockVideo1 = [{
87
+ adUnitCode: 'video1',
88
+ auctionId: '01618029-7ae9-4e98-a73a-1ed0c817f414',
89
+ bidId: '2a59588c0114fa',
90
+ bidRequestsCount: 1,
91
+ bidder: 'pilotx',
92
+ bidderRequestId: '1f6b4ba2039726',
93
+ bidderRequestsCount: 1,
94
+ bidderWinsCount: 0,
95
+ crumbs: { pubcid: 'de5240ef-ff80-4b55-8837-26a11cfbf64c' },
96
+ mediaTypes: {
97
+ video: {
98
+ context: 'instream',
99
+ mimes: ['video/mp4'],
100
+ playbackmethod: [2],
101
+ playerSize: [[640, 480]],
102
+ protocols: [1, 2, 3, 4, 5, 6, 7, 8],
103
+ skip: 1
104
+ }
105
+ },
106
+ ortb2Imp: {
107
+ ext: {
108
+ data: {
109
+ pbadslot: 'video1'
110
+ }
111
+ }
112
+ },
113
+ params: { placementId: '379' },
114
+ sizes: [[640, 480]],
115
+ src: 'client',
116
+ transactionId: 'fec9f2ff-da13-4921-8437-8d679c2be7fe',
117
+ }];
118
+ const mockVideo2 = [{
119
+ adUnitCode: 'video1',
120
+ auctionId: '01618029-7ae9-4e98-a73a-1ed0c817f414',
121
+ bidId: '2a59588c0114fa',
122
+ bidRequestsCount: 1,
123
+ bidder: 'pilotx',
124
+ bidderRequestId: '1f6b4ba2039726',
125
+ bidderRequestsCount: 1,
126
+ bidderWinsCount: 0,
127
+ crumbs: { pubcid: 'de5240ef-ff80-4b55-8837-26a11cfbf64c' },
128
+ mediaTypes: {
129
+ video: {
130
+ context: 'instream',
131
+ mimes: ['video/mp4'],
132
+ playbackmethod: [2],
133
+ playerSize: [[640, 480]],
134
+ protocols: [1, 2, 3, 4, 5, 6, 7, 8],
135
+ skip: 1
136
+ }
137
+ },
138
+ ortb2Imp: {
139
+ ext: {
140
+ data: {
141
+ pbadslot: 'video1'
142
+ }
143
+ }
144
+ },
145
+ params: { placementId: '379' },
146
+ sizes: [640, 480],
147
+ src: 'client',
148
+ transactionId: 'fec9f2ff-da13-4921-8437-8d679c2be7fe',
149
+ }];
150
+ it('should return correct response', function () {
151
+ const builtRequest = spec.buildRequests(mockVideo1, mockRequest)
152
+ let builtRequestData = builtRequest.data
153
+ let data = JSON.parse(builtRequestData)
154
+ expect(data['379'].bidId).to.equal(mockVideo1[0].bidId)
155
+ });
156
+ it('should return correct response for only array of size', function () {
157
+ const builtRequest = spec.buildRequests(mockVideo2, mockRequest)
158
+ let builtRequestData = builtRequest.data
159
+ let data = JSON.parse(builtRequestData)
160
+ expect(data['379'].sizes[0][0]).to.equal(mockVideo2[0].sizes[0])
161
+ expect(data['379'].sizes[0][1]).to.equal(mockVideo2[0].sizes[1])
162
+ });
163
+ it('should be valid and pass gdpr items correctly', function () {
164
+ const builtRequest = spec.buildRequests(mockVideo2, mockRequestGDPR)
165
+ let builtRequestData = builtRequest.data
166
+ let data = JSON.parse(builtRequestData)
167
+ expect(data['379'].gdprConsentString).to.equal(mockRequestGDPR.gdprConsent.consentString)
168
+ expect(data['379'].gdprConsentRequired).to.equal(mockRequestGDPR.gdprConsent.gdprApplies)
169
+ });
170
+ });
171
+ describe('interpretResponse', function () {
172
+ const bidRequest = {}
173
+ const serverResponse = {
174
+ cpm: 2.5,
175
+ creativeId: 'V9060',
176
+ currency: 'US',
177
+ height: 480,
178
+ mediaType: 'video',
179
+ netRevenue: false,
180
+ requestId: '273b39c74069cb',
181
+ ttl: 3000,
182
+ vastUrl: 'http://testadserver.com/ads?&k=60cd901ad8ab70c9cedf373cb17b93b8&pid=379&tid=91342717',
183
+ width: 640
184
+ }
185
+ const serverResponseVideo = {
186
+ body: serverResponse
187
+ }
188
+ const serverResponse2 = {
189
+ cpm: 2.5,
190
+ creativeId: 'V9060',
191
+ currency: 'US',
192
+ height: 480,
193
+ mediaType: 'banner',
194
+ netRevenue: false,
195
+ requestId: '273b39c74069cb',
196
+ ttl: 3000,
197
+ vastUrl: 'http://testadserver.com/ads?&k=60cd901ad8ab70c9cedf373cb17b93b8&pid=379&tid=91342717',
198
+ width: 640
199
+ }
200
+ const serverResponseBanner = {
201
+ body: serverResponse2
202
+ }
203
+ it('should be valid from bidRequest for video', function () {
204
+ const bidResponses = spec.interpretResponse(serverResponseVideo, bidRequest)
205
+ expect(bidResponses[0].requestId).to.equal(serverResponse.requestId)
206
+ expect(bidResponses[0].cpm).to.equal(serverResponse.cpm)
207
+ expect(bidResponses[0].width).to.equal(serverResponse.width)
208
+ expect(bidResponses[0].height).to.equal(serverResponse.height)
209
+ expect(bidResponses[0].creativeId).to.equal(serverResponse.creativeId)
210
+ expect(bidResponses[0].currency).to.equal(serverResponse.currency)
211
+ expect(bidResponses[0].netRevenue).to.equal(serverResponse.netRevenue)
212
+ expect(bidResponses[0].ttl).to.equal(serverResponse.ttl)
213
+ expect(bidResponses[0].vastUrl).to.equal(serverResponse.vastUrl)
214
+ expect(bidResponses[0].mediaType).to.equal(serverResponse.mediaType)
215
+ expect(bidResponses[0].meta.mediaType).to.equal(serverResponse.mediaType)
216
+ });
217
+ it('should be valid from bidRequest for banner', function () {
218
+ const bidResponses = spec.interpretResponse(serverResponseBanner, bidRequest)
219
+ expect(bidResponses[0].requestId).to.equal(serverResponse2.requestId)
220
+ expect(bidResponses[0].cpm).to.equal(serverResponse2.cpm)
221
+ expect(bidResponses[0].width).to.equal(serverResponse2.width)
222
+ expect(bidResponses[0].height).to.equal(serverResponse2.height)
223
+ expect(bidResponses[0].creativeId).to.equal(serverResponse2.creativeId)
224
+ expect(bidResponses[0].currency).to.equal(serverResponse2.currency)
225
+ expect(bidResponses[0].netRevenue).to.equal(serverResponse2.netRevenue)
226
+ expect(bidResponses[0].ttl).to.equal(serverResponse2.ttl)
227
+ expect(bidResponses[0].ad).to.equal(serverResponse2.ad)
228
+ expect(bidResponses[0].mediaType).to.equal(serverResponse2.mediaType)
229
+ expect(bidResponses[0].meta.mediaType).to.equal(serverResponse2.mediaType)
230
+ });
231
+ });
232
+ describe('setPlacementID', function () {
233
+ const multiplePlacementIds = ['380', '381']
234
+ it('should be valid with an array of placement ids passed', function () {
235
+ const placementID = spec.setPlacementID(multiplePlacementIds)
236
+ expect(placementID).to.equal('380#381')
237
+ });
238
+ it('should be valid with single placement ID passed', function () {
239
+ const placementID = spec.setPlacementID('381')
240
+ expect(placementID).to.equal('381')
241
+ });
242
+ });
243
+ // Add other `describe` or `it` blocks as necessary
244
+ });
@@ -141,7 +141,56 @@ describe('Real time module', function () {
141
141
  const adUnits = rtdModule.getAdUnitTargeting(auction);
142
142
  assert.deepEqual(expectedAdUnits, adUnits)
143
143
  done();
144
- })
144
+ });
145
+
146
+ describe('setBidRequestData', () => {
147
+ let withWait, withoutWait;
148
+
149
+ function runSetBidRequestData() {
150
+ return new Promise((resolve) => {
151
+ rtdModule.setBidRequestsData(resolve, {bidRequest: {}});
152
+ });
153
+ }
154
+
155
+ beforeEach(() => {
156
+ withWait = {
157
+ submod: validSMWait,
158
+ cbTime: 0,
159
+ cbRan: false
160
+ };
161
+ withoutWait = {
162
+ submod: validSM,
163
+ cbTime: 0,
164
+ cbRan: false
165
+ };
166
+
167
+ [withWait, withoutWait].forEach((c) => {
168
+ c.submod.getBidRequestData = sinon.stub().callsFake((_, cb) => {
169
+ setTimeout(() => {
170
+ c.cbRan = true;
171
+ cb();
172
+ }, c.cbTime);
173
+ });
174
+ });
175
+ });
176
+
177
+ it('should allow non-priority submodules to run synchronously', () => {
178
+ withWait.cbTime = withoutWait.cbTime = 0;
179
+ return runSetBidRequestData().then(() => {
180
+ expect(withWait.cbRan).to.be.true;
181
+ expect(withoutWait.cbRan).to.be.true;
182
+ })
183
+ });
184
+
185
+ it('should not wait for non-priority submodules if priority ones complete first', () => {
186
+ withWait.cbTime = 10;
187
+ withoutWait.cbTime = 100;
188
+ return runSetBidRequestData().then(() => {
189
+ expect(withWait.cbRan).to.be.true;
190
+ expect(withoutWait.cbRan).to.be.false;
191
+ });
192
+ });
193
+ });
145
194
  });
146
195
 
147
196
  it('deep merge object', function () {
@@ -255,5 +304,5 @@ describe('Real time module', function () {
255
304
  expect(providers[1][hook].called).to.be.true;
256
305
  });
257
306
  });
258
- })
307
+ });
259
308
  });
@@ -987,6 +987,36 @@ describe('rubicon analytics adapter', function () {
987
987
  expect(message.auctions[0].adUnits[1].bids[0].bidResponse.adomains).to.be.undefined;
988
988
  });
989
989
 
990
+ it('should NOT pass along adomians with other edge cases', function () {
991
+ events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
992
+ events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);
993
+
994
+ // should filter out non string values and pass valid ones
995
+ let bidResponse1 = utils.deepClone(MOCK.BID_RESPONSE[0]);
996
+ bidResponse1.meta = {
997
+ advertiserDomains: [123, 'prebid.org', false, true, [], 'magnite.com', {}]
998
+ }
999
+
1000
+ // array of arrays (as seen when passed by kargo bid adapter)
1001
+ let bidResponse2 = utils.deepClone(MOCK.BID_RESPONSE[1]);
1002
+ bidResponse2.meta = {
1003
+ advertiserDomains: [['prebid.org']]
1004
+ }
1005
+
1006
+ events.emit(BID_RESPONSE, bidResponse1);
1007
+ events.emit(BID_RESPONSE, bidResponse2);
1008
+ events.emit(BIDDER_DONE, MOCK.BIDDER_DONE);
1009
+ events.emit(AUCTION_END, MOCK.AUCTION_END);
1010
+ events.emit(SET_TARGETING, MOCK.SET_TARGETING);
1011
+ events.emit(BID_WON, MOCK.BID_WON[0]);
1012
+ events.emit(BID_WON, MOCK.BID_WON[1]);
1013
+
1014
+ let message = JSON.parse(server.requests[0].requestBody);
1015
+ validate(message);
1016
+ expect(message.auctions[0].adUnits[0].bids[0].bidResponse.adomains).to.deep.equal(['prebid.org', 'magnite.com']);
1017
+ expect(message.auctions[0].adUnits[1].bids[0].bidResponse.adomains).to.be.undefined;
1018
+ });
1019
+
990
1020
  it('should not pass empty adServerTargeting values', function () {
991
1021
  events.emit(AUCTION_INIT, MOCK.AUCTION_INIT);
992
1022
  events.emit(BID_REQUESTED, MOCK.BID_REQUESTED);