prebid.js 7.0.0 → 7.1.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 (182) hide show
  1. package/bundle-template.txt +2 -2
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/adWMGAnalyticsAdapter.js +1 -1
  4. package/dist/adagioAnalyticsAdapter.js +1 -1
  5. package/dist/adagioBidAdapter.js +1 -1
  6. package/dist/adbookpspBidAdapter.js +1 -1
  7. package/dist/adgenerationBidAdapter.js +1 -1
  8. package/dist/adkernelAdnAnalyticsAdapter.js +1 -1
  9. package/dist/adlooxAdServerVideo.js +1 -1
  10. package/dist/adlooxAnalyticsAdapter.js +1 -1
  11. package/dist/adlooxRtdProvider.js +1 -1
  12. package/dist/adomikAnalyticsAdapter.js +1 -1
  13. package/dist/adrelevantisBidAdapter.js +1 -1
  14. package/dist/aduptechBidAdapter.js +1 -1
  15. package/dist/adxcgAnalyticsAdapter.js +1 -1
  16. package/dist/adxcgBidAdapter.js +1 -1
  17. package/dist/adxpremiumAnalyticsAdapter.js +1 -1
  18. package/dist/ajaBidAdapter.js +1 -1
  19. package/dist/amxBidAdapter.js +1 -1
  20. package/dist/amxIdSystem.js +1 -1
  21. package/dist/appierAnalyticsAdapter.js +1 -1
  22. package/dist/appnexusBidAdapter.js +1 -1
  23. package/dist/asoBidAdapter.js +1 -1
  24. package/dist/atsAnalyticsAdapter.js +1 -1
  25. package/dist/axonixBidAdapter.js +1 -1
  26. package/dist/bidglassBidAdapter.js +1 -1
  27. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  28. package/dist/big-richmediaBidAdapter.js +1 -1
  29. package/dist/bridgewellBidAdapter.js +1 -1
  30. package/dist/brightMountainMediaBidAdapter.js +1 -1
  31. package/dist/byDataAnalyticsAdapter.js +1 -1
  32. package/dist/concertAnalyticsAdapter.js +1 -1
  33. package/dist/concertBidAdapter.js +1 -1
  34. package/dist/connectadBidAdapter.js +1 -1
  35. package/dist/consentManagement.js +1 -1
  36. package/dist/consumableBidAdapter.js +1 -1
  37. package/dist/conversantBidAdapter.js +1 -1
  38. package/dist/craftBidAdapter.js +1 -1
  39. package/dist/criteoBidAdapter.js +1 -1
  40. package/dist/cwireBidAdapter.js +1 -1
  41. package/dist/datablocksAnalyticsAdapter.js +1 -1
  42. package/dist/dspxBidAdapter.js +1 -1
  43. package/dist/eplanningAnalyticsAdapter.js +1 -1
  44. package/dist/eplanningBidAdapter.js +1 -1
  45. package/dist/fintezaAnalyticsAdapter.js +1 -1
  46. package/dist/getOrigin.js +1 -0
  47. package/dist/glimpseBidAdapter.js +1 -1
  48. package/dist/gmosspBidAdapter.js +1 -1
  49. package/dist/goldbachBidAdapter.js +1 -1
  50. package/dist/gridBidAdapter.js +1 -1
  51. package/dist/gridNMBidAdapter.js +1 -1
  52. package/dist/gumgumBidAdapter.js +1 -1
  53. package/dist/h12mediaBidAdapter.js +1 -1
  54. package/dist/hadronAnalyticsAdapter.js +1 -1
  55. package/dist/id5AnalyticsAdapter.js +1 -1
  56. package/dist/id5IdSystem.js +1 -1
  57. package/dist/improvedigitalBidAdapter.js +1 -1
  58. package/dist/inmarBidAdapter.js +1 -1
  59. package/dist/insticatorBidAdapter.js +1 -1
  60. package/dist/invisiblyAnalyticsAdapter.js +1 -1
  61. package/dist/ixBidAdapter.js +1 -1
  62. package/dist/justpremiumBidAdapter.js +1 -1
  63. package/dist/kargoAnalyticsAdapter.js +1 -1
  64. package/dist/konduitAnalyticsAdapter.js +1 -1
  65. package/dist/livewrappedAnalyticsAdapter.js +1 -1
  66. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  67. package/dist/logicadBidAdapter.js +1 -1
  68. package/dist/loglyliftBidAdapter.js +1 -1
  69. package/dist/malltvAnalyticsAdapter.js +1 -1
  70. package/dist/marsmediaAnalyticsAdapter.js +1 -1
  71. package/dist/marsmediaBidAdapter.js +1 -1
  72. package/dist/mediafuseBidAdapter.js +1 -1
  73. package/dist/medianetAnalyticsAdapter.js +1 -1
  74. package/dist/mediasquareBidAdapter.js +1 -1
  75. package/dist/mgidBidAdapter.js +1 -1
  76. package/dist/minutemediaBidAdapter.js +1 -1
  77. package/dist/not-for-prod/prebid.js +150 -147
  78. package/dist/oguryBidAdapter.js +1 -1
  79. package/dist/onetagBidAdapter.js +1 -1
  80. package/dist/ooloAnalyticsAdapter.js +1 -1
  81. package/dist/openxAnalyticsAdapter.js +1 -1
  82. package/dist/optimonAnalyticsAdapter.js +1 -1
  83. package/dist/outbrainBidAdapter.js +1 -1
  84. package/dist/parrableIdSystem.js +1 -1
  85. package/dist/pianoDmpAnalyticsAdapter.js +1 -0
  86. package/dist/pixfutureBidAdapter.js +1 -1
  87. package/dist/prebid-core.js +1 -1
  88. package/dist/prebidmanagerAnalyticsAdapter.js +1 -1
  89. package/dist/publinkIdSystem.js +1 -1
  90. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  91. package/dist/pubmaticBidAdapter.js +1 -1
  92. package/dist/pubperfAnalyticsAdapter.js +1 -1
  93. package/dist/pubstackAnalyticsAdapter.js +1 -1
  94. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  95. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  96. package/dist/pulsepointAnalyticsAdapter.js +1 -1
  97. package/dist/pxyzBidAdapter.js +1 -1
  98. package/dist/quantcastBidAdapter.js +1 -1
  99. package/dist/readpeakBidAdapter.js +1 -1
  100. package/dist/realvuAnalyticsAdapter.js +1 -1
  101. package/dist/relaidoBidAdapter.js +1 -1
  102. package/dist/relevantAnalyticsAdapter.js +1 -1
  103. package/dist/resetdigitalBidAdapter.js +1 -1
  104. package/dist/rhythmoneBidAdapter.js +1 -1
  105. package/dist/riseBidAdapter.js +1 -1
  106. package/dist/rivrAnalyticsAdapter.js +1 -1
  107. package/dist/roxotAnalyticsAdapter.js +1 -1
  108. package/dist/rtbhouseBidAdapter.js +1 -1
  109. package/dist/rubiconAnalyticsAdapter.js +1 -1
  110. package/dist/rubiconBidAdapter.js +1 -1
  111. package/dist/scaleableAnalyticsAdapter.js +1 -1
  112. package/dist/seedingAllianceBidAdapter.js +1 -1
  113. package/dist/seedtagBidAdapter.js +1 -1
  114. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  115. package/dist/sharethroughBidAdapter.js +1 -1
  116. package/dist/sigmoidAnalyticsAdapter.js +1 -1
  117. package/dist/smaatoBidAdapter.js +1 -1
  118. package/dist/smartadserverBidAdapter.js +1 -1
  119. package/dist/smartxBidAdapter.js +1 -1
  120. package/dist/smilewantedBidAdapter.js +1 -1
  121. package/dist/sonobiAnalyticsAdapter.js +1 -1
  122. package/dist/sonobiBidAdapter.js +1 -1
  123. package/dist/sovrnAnalyticsAdapter.js +1 -1
  124. package/dist/sovrnBidAdapter.js +1 -1
  125. package/dist/sspBCBidAdapter.js +1 -1
  126. package/dist/staqAnalyticsAdapter.js +1 -1
  127. package/dist/sublimeBidAdapter.js +1 -1
  128. package/dist/synacormediaBidAdapter.js +1 -1
  129. package/dist/targetVideoBidAdapter.js +1 -1
  130. package/dist/teadsBidAdapter.js +1 -1
  131. package/dist/terceptAnalyticsAdapter.js +1 -1
  132. package/dist/trafficgateBidAdapter.js +1 -0
  133. package/dist/trionBidAdapter.js +1 -1
  134. package/dist/tripleliftBidAdapter.js +1 -1
  135. package/dist/ttdBidAdapter.js +1 -1
  136. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  137. package/dist/underdogmediaBidAdapter.js +1 -1
  138. package/dist/undertoneBidAdapter.js +1 -1
  139. package/dist/vidazooBidAdapter.js +1 -1
  140. package/dist/videobyteBidAdapter.js +1 -1
  141. package/dist/visxBidAdapter.js +1 -1
  142. package/dist/vuukleBidAdapter.js +1 -1
  143. package/dist/widespaceBidAdapter.js +1 -1
  144. package/dist/winrBidAdapter.js +1 -1
  145. package/dist/yahoosspBidAdapter.js +1 -1
  146. package/dist/yieldmoBidAdapter.js +1 -1
  147. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  148. package/dist/yuktamediaAnalyticsAdapter.js +1 -1
  149. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  150. package/gulpHelpers.js +53 -16
  151. package/gulpfile.js +1 -0
  152. package/integrationExamples/gpt/gdpr_hello_world.html +14 -77
  153. package/karma.conf.maker.js +6 -0
  154. package/libraries/getOrigin/index.js +11 -0
  155. package/modules/.submodules.json +83 -69
  156. package/modules/aduptechBidAdapter.js +30 -0
  157. package/modules/adxpremiumAnalyticsAdapter.js +1 -0
  158. package/modules/consentManagement.js +15 -6
  159. package/modules/cwireBidAdapter.js +8 -2
  160. package/modules/cwireBidAdapter.md +3 -3
  161. package/modules/ooloAnalyticsAdapter.js +2 -1
  162. package/modules/pianoDmpAnalyticcsAdapter.md +13 -0
  163. package/modules/pianoDmpAnalyticsAdapter.js +38 -0
  164. package/modules/resetdigitalBidAdapter.js +2 -1
  165. package/modules/rtbhouseBidAdapter.js +2 -1
  166. package/modules/synacormediaBidAdapter.js +7 -0
  167. package/modules/trafficgateBidAdapter.js +92 -0
  168. package/modules/trafficgateBidAdapter.md +30 -0
  169. package/modules/tripleliftBidAdapter.js +27 -0
  170. package/package.json +1 -1
  171. package/src/AnalyticsAdapter.js +13 -6
  172. package/src/utils.js +0 -11
  173. package/test/spec/AnalyticsAdapter_spec.js +8 -0
  174. package/test/spec/modules/aduptechBidAdapter_spec.js +65 -0
  175. package/test/spec/modules/consentManagement_spec.js +75 -16
  176. package/test/spec/modules/cwireBidAdapter_spec.js +24 -11
  177. package/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js +66 -0
  178. package/test/spec/modules/synacormediaBidAdapter_spec.js +44 -0
  179. package/test/spec/modules/trafficgateBidAdapter_spec.js +223 -0
  180. package/test/spec/modules/tripleliftBidAdapter_spec.js +70 -1
  181. package/webpack.conf.js +14 -1
  182. package/integrationExamples/gpt/gdpr_indefinite_timeout_exampe.html +0 -151
@@ -37,6 +37,14 @@ FEATURE: Analytics Adapters API
37
37
  adapter.disableAnalytics();
38
38
  });
39
39
 
40
+ it('should track enable status in `enabled`', () => {
41
+ expect(adapter.enabled).to.equal(false);
42
+ adapter.enableAnalytics();
43
+ expect(adapter.enabled).to.equal(true);
44
+ adapter.disableAnalytics();
45
+ expect(adapter.enabled).to.equal(false);
46
+ })
47
+
40
48
  it(`SHOULD call the endpoint WHEN an event occurs that is to be tracked`, function () {
41
49
  const eventType = BID_REQUESTED;
42
50
  const args = { some: 'data' };
@@ -527,6 +527,71 @@ describe('AduptechBidAdapter', () => {
527
527
  }
528
528
  ]);
529
529
  });
530
+
531
+ it('should build a request with floorPrices', () => {
532
+ const bidderRequest = {
533
+ auctionId: 'auctionId123',
534
+ refererInfo: {
535
+ page: 'http://crazy.canonical.url',
536
+ ref: 'http://crazy.referer.url'
537
+ },
538
+ gdprConsent: {
539
+ consentString: 'consentString123',
540
+ gdprApplies: true
541
+ }
542
+ };
543
+
544
+ const getFloorResponse = {
545
+ currency: 'USD',
546
+ floor: '1.23'
547
+ };
548
+
549
+ const validBidRequests = [
550
+ {
551
+ bidId: 'bidId1',
552
+ adUnitCode: 'adUnitCode1',
553
+ transactionId: 'transactionId1',
554
+ mediaTypes: {
555
+ banner: {
556
+ sizes: [[100, 200], [300, 400]]
557
+ }
558
+ },
559
+ params: {
560
+ publisher: 'publisher1',
561
+ placement: 'placement1'
562
+ },
563
+ getFloor: () => {
564
+ return getFloorResponse
565
+ }
566
+ }
567
+ ];
568
+
569
+ expect(spec.buildRequests(validBidRequests, bidderRequest)).to.deep.equal([
570
+ {
571
+ url: internal.buildEndpointUrl(validBidRequests[0].params.publisher),
572
+ method: ENDPOINT_METHOD,
573
+ data: {
574
+ auctionId: bidderRequest.auctionId,
575
+ pageUrl: bidderRequest.refererInfo.page,
576
+ referrer: bidderRequest.refererInfo.ref,
577
+ gdpr: {
578
+ consentString: bidderRequest.gdprConsent.consentString,
579
+ consentRequired: bidderRequest.gdprConsent.gdprApplies
580
+ },
581
+ imp: [
582
+ {
583
+ bidId: validBidRequests[0].bidId,
584
+ transactionId: validBidRequests[0].transactionId,
585
+ adUnitCode: validBidRequests[0].adUnitCode,
586
+ params: validBidRequests[0].params,
587
+ banner: validBidRequests[0].mediaTypes.banner,
588
+ floorPrice: getFloorResponse.floor
589
+ }
590
+ ]
591
+ }
592
+ }
593
+ ]);
594
+ });
530
595
  });
531
596
 
532
597
  describe('interpretResponse', () => {
@@ -616,25 +616,84 @@ describe('consentManagement', function () {
616
616
  expect(gdprDataHandler.ready).to.be.true;
617
617
  });
618
618
 
619
- it('allows the auction when CMP is unresponsive', (done) => {
620
- setConsentConfig({
621
- cmpApi: 'iab',
622
- timeout: 10,
623
- defaultGdprScope: true
619
+ describe('when proper consent is not available', () => {
620
+ let tcfStub;
621
+
622
+ function runAuction() {
623
+ setConsentConfig({
624
+ cmpApi: 'iab',
625
+ timeout: 10,
626
+ defaultGdprScope: true
627
+ });
628
+ return new Promise((resolve, reject) => {
629
+ requestBidsHook(() => {
630
+ didHookReturn = true;
631
+ }, {});
632
+ setTimeout(() => didHookReturn ? resolve() : reject(new Error('Auction did not run')), 20);
633
+ })
634
+ }
635
+
636
+ function mockTcfEvent(tcdata) {
637
+ tcfStub.callsFake((api, version, cb) => {
638
+ if (api === 'addEventListener' && version === 2) {
639
+ // eslint-disable-next-line standard/no-callback-literal
640
+ cb(tcdata, true)
641
+ }
642
+ });
643
+ }
644
+
645
+ beforeEach(() => {
646
+ tcfStub = sinon.stub(window, '__tcfapi');
624
647
  });
625
648
 
626
- requestBidsHook(() => {
627
- didHookReturn = true;
628
- }, {});
649
+ afterEach(() => {
650
+ tcfStub.restore();
651
+ })
652
+
653
+ it('should continue auction with null consent when CMP is unresponsive', () => {
654
+ return runAuction().then(() => {
655
+ const consent = gdprDataHandler.getConsentData();
656
+ expect(consent.gdprApplies).to.be.true;
657
+ expect(consent.consentString).to.be.undefined;
658
+ expect(gdprDataHandler.ready).to.be.true;
659
+ });
660
+ });
629
661
 
630
- setTimeout(() => {
631
- expect(didHookReturn).to.be.true;
632
- const consent = gdprDataHandler.getConsentData();
633
- expect(consent.gdprApplies).to.be.true;
634
- expect(consent.consentString).to.be.undefined;
635
- expect(gdprDataHandler.ready).to.be.true;
636
- done();
637
- }, 20);
662
+ it('should use consent provided by events other than tcloaded', () => {
663
+ mockTcfEvent({
664
+ eventStatus: 'cmpuishown',
665
+ tcString: 'mock-consent-string',
666
+ vendorData: {}
667
+ });
668
+ return runAuction().then(() => {
669
+ const consent = gdprDataHandler.getConsentData();
670
+ expect(consent.gdprApplies).to.be.true;
671
+ expect(consent.consentString).to.equal('mock-consent-string');
672
+ expect(consent.vendorData.vendorData).to.eql({});
673
+ expect(gdprDataHandler.ready).to.be.true;
674
+ });
675
+ });
676
+
677
+ Object.entries({
678
+ 'null': null,
679
+ 'empty': '',
680
+ 'undefined': undefined
681
+ }).forEach(([t, cs]) => {
682
+ // some CMPs appear to reply with an empty consent string in 'cmpuishown' - make sure we don't use that
683
+ it(`should NOT use "default" consent if string is ${t}`, () => {
684
+ mockTcfEvent({
685
+ eventStatus: 'cmpuishown',
686
+ tcString: cs,
687
+ vendorData: {random: 'junk'}
688
+ });
689
+ return runAuction().then(() => {
690
+ const consent = gdprDataHandler.getConsentData();
691
+ expect(consent.gdprApplies).to.be.true;
692
+ expect(consent.consentString).to.be.undefined;
693
+ expect(consent.vendorData).to.be.undefined;
694
+ });
695
+ })
696
+ });
638
697
  });
639
698
 
640
699
  it('It still considers it a valid cmp response if gdprApplies is not a boolean', function () {
@@ -120,6 +120,19 @@ describe('C-WIRE bid adapter', () => {
120
120
  bid01.params.pageId = '3320';
121
121
  expect(spec.isBidRequestValid(bid01)).to.equal(false);
122
122
  });
123
+
124
+ it('should fail if cwcreative of type number', function () {
125
+ const bid01 = new BidRequestBuilder().withParams().build();
126
+ delete bid01.params.cwcreative;
127
+ bid01.params.cwcreative = 3320;
128
+ expect(spec.isBidRequestValid(bid01)).to.equal(false);
129
+ });
130
+
131
+ it('should pass with valid cwcreative of type string', function () {
132
+ const bid01 = new BidRequestBuilder().withParams().build();
133
+ bid01.params.cwcreative = 'i-am-a-string';
134
+ expect(spec.isBidRequestValid(bid01)).to.equal(true);
135
+ });
123
136
  });
124
137
 
125
138
  describe('C-WIRE - buildRequests()', function () {
@@ -131,7 +144,7 @@ describe('C-WIRE bid adapter', () => {
131
144
  }
132
145
  }
133
146
  }).withParams({
134
- cwcreative: 54321,
147
+ cwcreative: '54321',
135
148
  cwapikey: 'xxx-xxx-yyy-zzz-uuid',
136
149
  refgroups: 'group_1',
137
150
  }).build();
@@ -144,7 +157,7 @@ describe('C-WIRE bid adapter', () => {
144
157
  expect(requests.data.cwid).to.be.null;
145
158
  expect(requests.data.cwid).to.be.null;
146
159
  expect(requests.data.slots[0].sizes[0]).to.equal('1x1');
147
- expect(requests.data.cwcreative).to.equal(54321);
160
+ expect(requests.data.cwcreative).to.equal('54321');
148
161
  expect(requests.data.cwapikey).to.equal('xxx-xxx-yyy-zzz-uuid');
149
162
  expect(requests.data.refgroups[0]).to.equal('group_1');
150
163
  });
@@ -159,7 +172,7 @@ describe('C-WIRE bid adapter', () => {
159
172
  }
160
173
  }
161
174
  }).withParams({
162
- cwcreative: 1234,
175
+ cwcreative: '1234',
163
176
  cwapikey: 'api_key_5',
164
177
  refgroups: 'group_5',
165
178
  }).build();
@@ -171,7 +184,7 @@ describe('C-WIRE bid adapter', () => {
171
184
  expect(requests.data.slots.length).to.equal(2);
172
185
  expect(requests.data.cwid).to.be.null;
173
186
  expect(requests.data.cwid).to.be.null;
174
- expect(requests.data.cwcreative).to.equal(1234);
187
+ expect(requests.data.cwcreative).to.equal('1234');
175
188
  expect(requests.data.cwapikey).to.equal('api_key_5');
176
189
  expect(requests.data.refgroups[0]).to.equal('group_5');
177
190
  });
@@ -179,14 +192,14 @@ describe('C-WIRE bid adapter', () => {
179
192
  it('creates a valid request - read debug params from first bid, ignore second', function () {
180
193
  const bid01 = new BidRequestBuilder()
181
194
  .withParams({
182
- cwcreative: 33,
195
+ cwcreative: '33',
183
196
  cwapikey: 'api_key_33',
184
197
  refgroups: 'group_33',
185
198
  }).build();
186
199
 
187
200
  const bid02 = new BidRequestBuilder()
188
201
  .withParams({
189
- cwcreative: 1234,
202
+ cwcreative: '1234',
190
203
  cwapikey: 'api_key_5',
191
204
  refgroups: 'group_5',
192
205
  }).build();
@@ -198,7 +211,7 @@ describe('C-WIRE bid adapter', () => {
198
211
  expect(requests.data.slots.length).to.equal(2);
199
212
  expect(requests.data.cwid).to.be.null;
200
213
  expect(requests.data.cwid).to.be.null;
201
- expect(requests.data.cwcreative).to.equal(33);
214
+ expect(requests.data.cwcreative).to.equal('33');
202
215
  expect(requests.data.cwapikey).to.equal('api_key_33');
203
216
  expect(requests.data.refgroups[0]).to.equal('group_33');
204
217
  });
@@ -206,7 +219,7 @@ describe('C-WIRE bid adapter', () => {
206
219
  it('creates a valid request - read debug params from 3 different slots', function () {
207
220
  const bid01 = new BidRequestBuilder()
208
221
  .withParams({
209
- cwcreative: 33,
222
+ cwcreative: '33',
210
223
  }).build();
211
224
 
212
225
  const bid02 = new BidRequestBuilder()
@@ -225,7 +238,7 @@ describe('C-WIRE bid adapter', () => {
225
238
  expect(requests.data.slots.length).to.equal(3);
226
239
  expect(requests.data.cwid).to.be.null;
227
240
  expect(requests.data.cwid).to.be.null;
228
- expect(requests.data.cwcreative).to.equal(33);
241
+ expect(requests.data.cwcreative).to.equal('33');
229
242
  expect(requests.data.cwapikey).to.equal('api_key_5');
230
243
  expect(requests.data.refgroups[0]).to.equal('group_5');
231
244
  });
@@ -244,7 +257,7 @@ describe('C-WIRE bid adapter', () => {
244
257
  }
245
258
  }
246
259
  }).withParams({
247
- cwcreative: 54321,
260
+ cwcreative: '54321',
248
261
  cwapikey: 'xxx-xxx-yyy-zzz',
249
262
  refgroups: 'group_1',
250
263
  }).build();
@@ -257,7 +270,7 @@ describe('C-WIRE bid adapter', () => {
257
270
  expect(requests.data.cwid).to.be.null;
258
271
  expect(requests.data.cwid).to.be.null;
259
272
  expect(requests.data.slots[0].sizes[0]).to.equal('1x1');
260
- expect(requests.data.cwcreative).to.equal(654321);
273
+ expect(requests.data.cwcreative).to.equal('654321');
261
274
  expect(requests.data.cwapikey).to.equal('xxx-xxx-yyy-zzz');
262
275
  expect(requests.data.refgroups[0]).to.equal('group_2');
263
276
  });
@@ -0,0 +1,66 @@
1
+ import pianoDmpAnalytics from 'modules/pianoDmpAnalyticsAdapter.js';
2
+ import adapterManager from 'src/adapterManager';
3
+ import * as events from 'src/events';
4
+ import constants from 'src/constants.json';
5
+ import { expect } from 'chai';
6
+
7
+ describe('Piano DMP Analytics Adapter', () => {
8
+ let sandbox;
9
+
10
+ beforeEach(() => {
11
+ sandbox = sinon.createSandbox();
12
+
13
+ sandbox.stub(events, 'getEvents').returns([]);
14
+ });
15
+
16
+ afterEach(() => {
17
+ sandbox.restore();
18
+ });
19
+
20
+ describe('track', () => {
21
+ beforeEach(() => {
22
+ adapterManager.enableAnalytics({
23
+ provider: 'pianoDmp',
24
+ });
25
+ });
26
+
27
+ afterEach(() => {
28
+ delete window.cX;
29
+ pianoDmpAnalytics.disableAnalytics();
30
+ });
31
+
32
+ it('should pass events to call queue', () => {
33
+ const eventsList = [
34
+ constants.EVENTS.AUCTION_INIT,
35
+ constants.EVENTS.AUCTION_END,
36
+ constants.EVENTS.BID_ADJUSTMENT,
37
+ constants.EVENTS.BID_TIMEOUT,
38
+ constants.EVENTS.BID_REQUESTED,
39
+ constants.EVENTS.BID_RESPONSE,
40
+ constants.EVENTS.NO_BID,
41
+ constants.EVENTS.BID_WON,
42
+ ];
43
+
44
+ // Given
45
+ const testEvents = eventsList.map((event) => ({
46
+ event,
47
+ args: { test: event },
48
+ }));
49
+
50
+ // When
51
+ testEvents.forEach(({ event, args }) => events.emit(event, args));
52
+
53
+ // Then
54
+ const callQueue = (window.cX || {}).callQueue;
55
+
56
+ expect(callQueue).to.be.an('array');
57
+ expect(callQueue.length).to.equal(testEvents.length);
58
+
59
+ callQueue.forEach(([method, params], index) => {
60
+ expect(method).to.equal('prebid');
61
+ expect(params.eventType).to.equal(testEvents[index].event);
62
+ expect(params.params).to.deep.equal(testEvents[index].args);
63
+ });
64
+ });
65
+ });
66
+ });
@@ -183,6 +183,14 @@ describe('synacormediaBidAdapter ', function () {
183
183
  }
184
184
  };
185
185
 
186
+ let bidderRequestWithTimeout = {
187
+ auctionId: 'xyz123',
188
+ refererInfo: {
189
+ referer: 'https://test.com/foo/bar'
190
+ },
191
+ timeout: 3000
192
+ };
193
+
186
194
  let bidderRequestWithCCPA = {
187
195
  auctionId: 'xyz123',
188
196
  refererInfo: {
@@ -295,6 +303,42 @@ describe('synacormediaBidAdapter ', function () {
295
303
  expect(reqVideo.data.imp).to.eql([expectedDataVideo1]);
296
304
  });
297
305
 
306
+ it('should return no tmax', function () {
307
+ let req = spec.buildRequests([validBidRequest], bidderRequest);
308
+ expect(req.data).to.not.have.property('tmax');
309
+ });
310
+
311
+ it('should return tmax equal to callback timeout', function () {
312
+ let req = spec.buildRequests([validBidRequest], bidderRequestWithTimeout);
313
+ expect(req.data.tmax).to.eql(bidderRequestWithTimeout.timeout);
314
+ });
315
+
316
+ it('should return tmax equal to smaller global timeout', function () {
317
+ let sandbox = sinon.sandbox.create();
318
+ sandbox.stub(config, 'getConfig').callsFake(key => {
319
+ const config = {
320
+ 'bidderTimeout': bidderRequestWithTimeout.timeout - 100
321
+ };
322
+ return config[key];
323
+ });
324
+ let req = spec.buildRequests([validBidRequest], bidderRequestWithTimeout);
325
+ sandbox.restore();
326
+ expect(req.data.tmax).to.eql(bidderRequestWithTimeout.timeout - 100);
327
+ });
328
+
329
+ it('should return tmax equal to smaller callback timeout', function () {
330
+ let sandbox = sinon.sandbox.create();
331
+ sandbox.stub(config, 'getConfig').callsFake(key => {
332
+ const config = {
333
+ 'bidderTimeout': bidderRequestWithTimeout.timeout + 100
334
+ };
335
+ return config[key];
336
+ });
337
+ let req = spec.buildRequests([validBidRequest], bidderRequestWithTimeout);
338
+ sandbox.restore();
339
+ expect(req.data.tmax).to.eql(bidderRequestWithTimeout.timeout);
340
+ });
341
+
298
342
  it('should return multiple bids when multiple valid requests with the same seatId are used', function () {
299
343
  let secondBidRequest = {
300
344
  bidId: 'foobar',
@@ -0,0 +1,223 @@
1
+ import { expect } from 'chai'
2
+ import { spec } from '../../../modules/trafficgateBidAdapter'
3
+ import { deepStrictEqual, notStrictEqual, ok, strictEqual } from 'assert'
4
+
5
+ describe('TrafficGateAdapter', () => {
6
+ const bid = {
7
+ bidId: '9ec5b177515ee2e5',
8
+ bidder: 'trafficgate',
9
+ params: {
10
+ placementId: 1,
11
+ host: 'example'
12
+ },
13
+ mediaTypes: {
14
+ banner: {
15
+ sizes: [[300, 250]]
16
+ }
17
+ }
18
+ }
19
+
20
+ describe('isBidRequestValid', () => {
21
+ it('Should return true if there are bidId, params and placementId parameters present', () => {
22
+ strictEqual(true, spec.isBidRequestValid(bid))
23
+ })
24
+
25
+ it('Should return false if at least one of parameters is not present', () => {
26
+ const b = { ...bid }
27
+ delete b.params.placementId
28
+ strictEqual(false, spec.isBidRequestValid(b))
29
+ })
30
+
31
+ it('Should return false if at least one of parameters is not present', () => {
32
+ const b = { ...bid }
33
+ delete b.params.host
34
+ strictEqual(false, spec.isBidRequestValid(b))
35
+ })
36
+ })
37
+
38
+ describe('buildRequests', () => {
39
+ const serverRequest = spec.buildRequests([bid])
40
+
41
+ it('Creates a ServerRequest object with method, URL and data', () => {
42
+ ok(serverRequest)
43
+ ok(serverRequest.method)
44
+ ok(serverRequest.url)
45
+ ok(serverRequest.data)
46
+ })
47
+
48
+ it('Returns POST method', () => {
49
+ strictEqual('POST', serverRequest.method)
50
+ })
51
+
52
+ it('Returns valid URL', () => {
53
+ strictEqual('https://example.bc-plugin.com/?c=o&m=multi', serverRequest.url)
54
+ })
55
+
56
+ it('Returns valid data if array of bids is valid', () => {
57
+ const { data } = serverRequest
58
+ strictEqual('object', typeof data)
59
+ deepStrictEqual(['language', 'secure', 'host', 'page', 'placements'], Object.keys(data))
60
+ strictEqual('string', typeof data.language)
61
+ strictEqual('string', typeof data.host)
62
+ strictEqual('string', typeof data.page)
63
+ notStrictEqual(-1, [0, 1].indexOf(data.secure))
64
+
65
+ const placement = data.placements[0]
66
+ deepStrictEqual(['placementId', 'bidId', 'traffic'], Object.keys(placement))
67
+ strictEqual(1, placement.placementId)
68
+ strictEqual('9ec5b177515ee2e5', placement.bidId)
69
+ strictEqual('banner', placement.traffic)
70
+ })
71
+
72
+ it('Returns empty data if no valid requests are passed', () => {
73
+ deepStrictEqual([], spec.buildRequests([]))
74
+ })
75
+ })
76
+
77
+ describe('interpretResponse', () => {
78
+ const validData = [
79
+ {
80
+ body: [{
81
+ mediaType: 'banner',
82
+ width: 300,
83
+ height: 250,
84
+ cpm: 0.4,
85
+ ad: 'Test',
86
+ requestId: '9ec5b177515ee2e5',
87
+ ttl: 120,
88
+ creativeId: '2',
89
+ netRevenue: true,
90
+ currency: 'USD',
91
+ dealId: '1',
92
+ meta: {
93
+ advertiserDomains: ['test.com']
94
+ }
95
+ }]
96
+ },
97
+ {
98
+ body: [{
99
+ vastUrl: 'example.com',
100
+ mediaType: 'video',
101
+ cpm: 0.5,
102
+ requestId: '9ec5b177515ee2e5',
103
+ ttl: 120,
104
+ creativeId: '2',
105
+ netRevenue: true,
106
+ currency: 'USD',
107
+ dealId: '1',
108
+ meta: {
109
+ advertiserDomains: ['test.com']
110
+ }
111
+ }]
112
+ },
113
+ {
114
+ body: [{
115
+ mediaType: 'native',
116
+ clickUrl: 'example.com',
117
+ title: 'Test',
118
+ image: 'example.com',
119
+ creativeId: '2',
120
+ impressionTrackers: ['example.com'],
121
+ ttl: 120,
122
+ cpm: 0.4,
123
+ requestId: '9ec5b177515ee2e5',
124
+ netRevenue: true,
125
+ currency: 'USD',
126
+ meta: {
127
+ advertiserDomains: ['test.com']
128
+ }
129
+ }]
130
+ }
131
+ ]
132
+
133
+ for (const obj of validData) {
134
+ const { mediaType } = obj.body[0]
135
+
136
+ it(`Should interpret ${mediaType} response`, () => {
137
+ const response = spec.interpretResponse(obj)
138
+
139
+ expect(response).to.be.an('array')
140
+ strictEqual(1, response.length)
141
+
142
+ const copy = { ...obj.body[0] }
143
+ deepStrictEqual(copy, response[0])
144
+ })
145
+ }
146
+
147
+ for (const obj of validData) {
148
+ it(`Should interpret response has meta.advertiserDomains`, () => {
149
+ const response = spec.interpretResponse(obj)
150
+
151
+ expect(response[0]['meta']['advertiserDomains']).to.be.an('array')
152
+ expect(response[0]['meta']['advertiserDomains'][0]).to.be.an('string')
153
+ })
154
+ }
155
+
156
+ const invalidData = [
157
+ {
158
+ body: [{
159
+ width: 300,
160
+ cpm: 0.4,
161
+ ad: 'Test',
162
+ requestId: '9ec5b177515ee2e5',
163
+ ttl: 120,
164
+ creativeId: '2',
165
+ netRevenue: true,
166
+ currency: 'USD',
167
+ dealId: '1'
168
+ }]
169
+ },
170
+ {
171
+ body: [{
172
+ mediaType: 'video',
173
+ cpm: 0.5,
174
+ requestId: '9ec5b177515ee2e5',
175
+ ttl: 120,
176
+ creativeId: '2',
177
+ netRevenue: true,
178
+ currency: 'USD',
179
+ dealId: '1'
180
+ }]
181
+ },
182
+ {
183
+ body: [{
184
+ mediaType: 'native',
185
+ clickUrl: 'example.com',
186
+ title: 'Test',
187
+ impressionTrackers: ['example.com'],
188
+ ttl: 120,
189
+ requestId: '9ec5b177515ee2e5',
190
+ creativeId: '2',
191
+ netRevenue: true,
192
+ currency: 'USD',
193
+ }]
194
+ }
195
+ ]
196
+
197
+ for (const obj of invalidData) {
198
+ const { mediaType } = obj.body[0]
199
+
200
+ it(`Should return an empty array if invalid ${mediaType} response is passed `, () => {
201
+ const response = spec.interpretResponse(obj)
202
+
203
+ expect(response).to.be.an('array')
204
+ strictEqual(0, response.length)
205
+ })
206
+ }
207
+
208
+ it('Should return an empty array if invalid response is passed', () => {
209
+ const response = spec.interpretResponse({
210
+ body: [{
211
+ ttl: 120,
212
+ creativeId: '2',
213
+ netRevenue: true,
214
+ currency: 'USD',
215
+ dealId: '1'
216
+ }]
217
+ })
218
+
219
+ expect(response).to.be.an('array')
220
+ strictEqual(0, response.length)
221
+ })
222
+ })
223
+ })