prebid.js 6.5.0 → 6.9.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 (139) hide show
  1. package/.eslintrc.js +8 -1
  2. package/integrationExamples/gpt/amp/creative.html +11 -33
  3. package/integrationExamples/gpt/weboramaRtdProvider_example.html +154 -115
  4. package/integrationExamples/gpt/x-domain/creative.html +63 -29
  5. package/modules/.submodules.json +2 -1
  6. package/modules/adagioBidAdapter.js +0 -8
  7. package/modules/adagioBidAdapter.md +1 -1
  8. package/modules/adbookpspBidAdapter.js +27 -10
  9. package/modules/adhashBidAdapter.js +3 -3
  10. package/modules/adkernelBidAdapter.js +2 -1
  11. package/modules/admanBidAdapter.js +10 -4
  12. package/modules/adomikAnalyticsAdapter.js +23 -11
  13. package/modules/adqueryIdSystem.js +103 -0
  14. package/modules/adqueryIdSystem.md +35 -0
  15. package/modules/appnexusBidAdapter.js +14 -2
  16. package/modules/asealBidAdapter.js +58 -0
  17. package/modules/asealBidAdapter.md +52 -0
  18. package/modules/bliinkBidAdapter.js +2 -1
  19. package/modules/brandmetricsRtdProvider.js +168 -0
  20. package/modules/brandmetricsRtdProvider.md +40 -0
  21. package/modules/colossussspBidAdapter.js +12 -8
  22. package/modules/colossussspBidAdapter.md +15 -1
  23. package/modules/compassBidAdapter.js +10 -3
  24. package/modules/consumableBidAdapter.md +1 -1
  25. package/modules/conversantBidAdapter.js +7 -0
  26. package/modules/criteoBidAdapter.js +10 -1
  27. package/modules/criteoIdSystem.js +29 -7
  28. package/modules/currency.js +26 -1
  29. package/modules/displayioBidAdapter.js +157 -0
  30. package/modules/displayioBidAdapter.md +148 -0
  31. package/modules/e_volutionBidAdapter.js +158 -0
  32. package/modules/glimpseBidAdapter.js +66 -44
  33. package/modules/gnetBidAdapter.js +3 -3
  34. package/modules/gnetBidAdapter.md +4 -4
  35. package/modules/gumgumBidAdapter.js +56 -42
  36. package/modules/idImportLibrary.js +45 -8
  37. package/modules/idImportLibrary.md +4 -0
  38. package/modules/improvedigitalBidAdapter.js +29 -2
  39. package/modules/interactiveOffersBidAdapter.js +9 -6
  40. package/modules/jwplayerRtdProvider.js +71 -6
  41. package/modules/jwplayerRtdProvider.md +27 -11
  42. package/modules/kargoBidAdapter.js +2 -2
  43. package/modules/lunamediahbBidAdapter.js +32 -4
  44. package/modules/nextMillenniumBidAdapter.js +3 -1
  45. package/modules/oguryBidAdapter.js +14 -14
  46. package/modules/onetagBidAdapter.js +4 -2
  47. package/modules/pilotxBidAdapter.js +147 -0
  48. package/modules/pilotxBidAdapter.md +50 -0
  49. package/modules/priceFloors.js +2 -1
  50. package/modules/proxistoreBidAdapter.js +0 -2
  51. package/modules/pubmaticAnalyticsAdapter.js +16 -0
  52. package/modules/richaudienceBidAdapter.js +10 -4
  53. package/modules/riseBidAdapter.js +18 -7
  54. package/modules/rtbhouseBidAdapter.js +14 -4
  55. package/modules/rtdModule/index.js +14 -15
  56. package/modules/rubiconAnalyticsAdapter.js +8 -2
  57. package/modules/seedingAllianceBidAdapter.js +3 -3
  58. package/modules/sharethroughBidAdapter.js +12 -17
  59. package/modules/showheroes-bsBidAdapter.js +13 -2
  60. package/modules/sortableAnalyticsAdapter.js +5 -4
  61. package/modules/sovrnBidAdapter.js +93 -18
  62. package/modules/sovrnBidAdapter.md +80 -2
  63. package/modules/synacormediaBidAdapter.js +31 -10
  64. package/modules/tappxBidAdapter.js +8 -5
  65. package/modules/teadsBidAdapter.js +1 -2
  66. package/modules/undertoneBidAdapter.js +17 -1
  67. package/modules/userId/eids.js +7 -1
  68. package/modules/userId/userId.md +8 -0
  69. package/modules/viewability.js +177 -0
  70. package/modules/viewability.md +87 -0
  71. package/modules/weboramaRtdProvider.js +264 -34
  72. package/modules/weboramaRtdProvider.md +110 -40
  73. package/modules/welectBidAdapter.js +106 -0
  74. package/modules/yahoosspBidAdapter.js +2 -0
  75. package/package.json +2 -1
  76. package/src/adRendering.js +38 -0
  77. package/src/adloader.js +2 -1
  78. package/src/auction.js +103 -73
  79. package/src/bidderSettings.js +69 -0
  80. package/src/hook.js +5 -1
  81. package/src/prebid.js +19 -21
  82. package/src/secureCreatives.js +131 -47
  83. package/src/targeting.js +3 -2
  84. package/src/utils.js +13 -10
  85. package/test/helpers/syncPromise.js +71 -0
  86. package/test/spec/auctionmanager_spec.js +179 -15
  87. package/test/spec/modules/adagioBidAdapter_spec.js +0 -10
  88. package/test/spec/modules/adbookpspBidAdapter_spec.js +17 -3
  89. package/test/spec/modules/adhashBidAdapter_spec.js +2 -2
  90. package/test/spec/modules/admanBidAdapter_spec.js +2 -2
  91. package/test/spec/modules/adomikAnalyticsAdapter_spec.js +3 -1
  92. package/test/spec/modules/adqueryIdSystem_spec.js +74 -0
  93. package/test/spec/modules/appnexusBidAdapter_spec.js +27 -0
  94. package/test/spec/modules/asealBidAdapter_spec.js +144 -0
  95. package/test/spec/modules/bliinkBidAdapter_spec.js +2 -0
  96. package/test/spec/modules/brandmetricsRtdProvider_spec.js +191 -0
  97. package/test/spec/modules/colossussspBidAdapter_spec.js +5 -2
  98. package/test/spec/modules/compassBidAdapter_spec.js +1 -0
  99. package/test/spec/modules/conversantBidAdapter_spec.js +54 -2
  100. package/test/spec/modules/criteoBidAdapter_spec.js +21 -0
  101. package/test/spec/modules/criteoIdSystem_spec.js +6 -3
  102. package/test/spec/modules/currency_spec.js +21 -6
  103. package/test/spec/modules/displayioBidAdapter_spec.js +239 -0
  104. package/test/spec/modules/e_volutionBidAdapter_spec.js +242 -0
  105. package/test/spec/modules/eids_spec.js +15 -0
  106. package/test/spec/modules/glimpseBidAdapter_spec.js +0 -18
  107. package/test/spec/modules/gnetBidAdapter_spec.js +6 -6
  108. package/test/spec/modules/gumgumBidAdapter_spec.js +46 -0
  109. package/test/spec/modules/idImportLibrary_spec.js +197 -10
  110. package/test/spec/modules/improvedigitalBidAdapter_spec.js +61 -0
  111. package/test/spec/modules/jwplayerRtdProvider_spec.js +195 -2
  112. package/test/spec/modules/kargoBidAdapter_spec.js +1 -1
  113. package/test/spec/modules/loglyliftBidAdapter_spec.js +1 -1
  114. package/test/spec/modules/lunamediahbBidAdapter_spec.js +27 -1
  115. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +1 -1
  116. package/test/spec/modules/oguryBidAdapter_spec.js +69 -3
  117. package/test/spec/modules/pilotxBidAdapter_spec.js +244 -0
  118. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +13 -1
  119. package/test/spec/modules/realTimeDataModule_spec.js +67 -5
  120. package/test/spec/modules/richaudienceBidAdapter_spec.js +40 -0
  121. package/test/spec/modules/riseBidAdapter_spec.js +31 -5
  122. package/test/spec/modules/rtbhouseBidAdapter_spec.js +20 -0
  123. package/test/spec/modules/rubiconAnalyticsAdapter_spec.js +61 -1
  124. package/test/spec/modules/sharethroughBidAdapter_spec.js +91 -6
  125. package/test/spec/modules/showheroes-bsBidAdapter_spec.js +2 -0
  126. package/test/spec/modules/sortableAnalyticsAdapter_spec.js +2 -3
  127. package/test/spec/modules/sovrnBidAdapter_spec.js +413 -333
  128. package/test/spec/modules/synacormediaBidAdapter_spec.js +70 -0
  129. package/test/spec/modules/tappxBidAdapter_spec.js +0 -19
  130. package/test/spec/modules/teadsBidAdapter_spec.js +14 -59
  131. package/test/spec/modules/undertoneBidAdapter_spec.js +55 -2
  132. package/test/spec/modules/userId_spec.js +68 -19
  133. package/test/spec/modules/viewability_spec.js +280 -0
  134. package/test/spec/modules/weboramaRtdProvider_spec.js +536 -20
  135. package/test/spec/modules/welectBidAdapter_spec.js +211 -0
  136. package/test/spec/modules/yahoosspBidAdapter_spec.js +10 -0
  137. package/test/spec/unit/core/bidderSettings_spec.js +123 -0
  138. package/test/spec/unit/pbjs_api_spec.js +21 -8
  139. package/test/spec/unit/secureCreatives_spec.js +143 -24
@@ -0,0 +1,211 @@
1
+ import { expect } from 'chai';
2
+ import { spec as adapter } from 'modules/welectBidAdapter.js';
3
+
4
+ describe('WelectAdapter', function () {
5
+ describe('Check methods existance', function () {
6
+ it('exists and is a function', function () {
7
+ expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function');
8
+ });
9
+ it('exists and is a function', function () {
10
+ expect(adapter.buildRequests).to.exist.and.to.be.a('function');
11
+ });
12
+ it('exists and is a function', function () {
13
+ expect(adapter.interpretResponse).to.exist.and.to.be.a('function');
14
+ });
15
+ });
16
+
17
+ describe('Check method isBidRequestValid return', function () {
18
+ let bid = {
19
+ bidder: 'welect',
20
+ params: {
21
+ placementId: 'exampleAlias',
22
+ domain: 'www.welect.de'
23
+ },
24
+ sizes: [[640, 360]],
25
+ mediaTypes: {
26
+ video: {
27
+ context: 'instream'
28
+ }
29
+ },
30
+ };
31
+ let bid2 = {
32
+ bidder: 'welect',
33
+ params: {
34
+ domain: 'www.welect.de'
35
+ },
36
+ mediaTypes: {
37
+ video: {
38
+ context: 'instream',
39
+ playerSize: [640, 360]
40
+ }
41
+ },
42
+ };
43
+
44
+ it('should be true', function () {
45
+ expect(adapter.isBidRequestValid(bid)).to.be.true;
46
+ });
47
+
48
+ it('should be false because the placementId is missing', function () {
49
+ expect(adapter.isBidRequestValid(bid2)).to.be.false;
50
+ });
51
+ });
52
+
53
+ describe('Check buildRequests method', function () {
54
+ // Bids to be formatted
55
+ let bid1 = {
56
+ bidder: 'welect',
57
+ params: {
58
+ placementId: 'exampleAlias'
59
+ },
60
+ sizes: [[640, 360]],
61
+ mediaTypes: {
62
+ video: {
63
+ context: 'instream'
64
+ }
65
+ },
66
+ bidId: 'abdc'
67
+ };
68
+ let bid2 = {
69
+ bidder: 'welect',
70
+ params: {
71
+ placementId: 'exampleAlias',
72
+ domain: 'www.welect2.de'
73
+ },
74
+ sizes: [[640, 360]],
75
+ mediaTypes: {
76
+ video: {
77
+ context: 'instream'
78
+ }
79
+ },
80
+ bidId: 'abdc',
81
+ gdprConsent: {
82
+ gdprApplies: 1,
83
+ gdprConsent: 'some_string'
84
+ }
85
+ };
86
+
87
+ let data1 = {
88
+ bid_id: 'abdc',
89
+ width: 640,
90
+ height: 360
91
+ }
92
+
93
+ let data2 = {
94
+ bid_id: 'abdc',
95
+ width: 640,
96
+ height: 360,
97
+ gdpr_consent: {
98
+ gdprApplies: 1,
99
+ tcString: 'some_string'
100
+ }
101
+ }
102
+
103
+ // Formatted requets
104
+ let request1 = {
105
+ method: 'POST',
106
+ url: 'https://www.welect.de/api/v2/preflight/exampleAlias',
107
+ data: data1,
108
+ options: {
109
+ contentType: 'application/json',
110
+ withCredentials: false,
111
+ crossOrigin: true,
112
+ }
113
+ };
114
+
115
+ let request2 = {
116
+ method: 'POST',
117
+ url: 'https://www.welect2.de/api/v2/preflight/exampleAlias',
118
+ data: data2,
119
+ options: {
120
+ contentType: 'application/json',
121
+ withCredentials: false,
122
+ crossOrigin: true,
123
+ }
124
+ }
125
+
126
+ it('defaults to www.welect.de, without gdpr object', function () {
127
+ expect(adapter.buildRequests([bid1])).to.deep.equal([request1]);
128
+ })
129
+
130
+ it('must return the right formatted requests, with gdpr object', function () {
131
+ expect(adapter.buildRequests([bid2])).to.deep.equal([request2]);
132
+ });
133
+ });
134
+
135
+ describe('Check interpretResponse method return', function () {
136
+ // invalid server response
137
+ let unavailableResponse = {
138
+ body: {
139
+ available: false
140
+ }
141
+ };
142
+
143
+ let availableResponse = {
144
+ body: {
145
+ available: true,
146
+ bidResponse: {
147
+ ad: {
148
+ video: 'some vast url'
149
+ },
150
+ meta: {
151
+ advertiserDomains: [],
152
+ },
153
+ cpm: 17,
154
+ creativeId: 'svmpreview',
155
+ currency: 'EUR',
156
+ netRevenue: true,
157
+ requestId: 'some bid id',
158
+ ttl: 120,
159
+ vastUrl: 'some vast url',
160
+ height: 640,
161
+ width: 320
162
+ }
163
+ }
164
+ }
165
+ // bid Request
166
+ let bid = {
167
+ data: {
168
+ bid_id: 'some bid id',
169
+ width: 640,
170
+ height: 320,
171
+ gdpr_consent: {
172
+ gdprApplies: 1,
173
+ tcString: 'some_string'
174
+ }
175
+ },
176
+ method: 'POST',
177
+ url: 'https://www.welect.de/api/v2/preflight/exampleAlias',
178
+ options: {
179
+ contentType: 'application/json',
180
+ withCredentials: false,
181
+ crossOrigin: true,
182
+ }
183
+ };
184
+ // Formatted reponse
185
+ let result = {
186
+ ad: {
187
+ video: 'some vast url'
188
+ },
189
+ meta: {
190
+ advertiserDomains: []
191
+ },
192
+ cpm: 17,
193
+ creativeId: 'svmpreview',
194
+ currency: 'EUR',
195
+ height: 640,
196
+ netRevenue: true,
197
+ requestId: 'some bid id',
198
+ ttl: 120,
199
+ vastUrl: 'some vast url',
200
+ width: 320
201
+ }
202
+
203
+ it('if response reflects unavailability, should be empty', function () {
204
+ expect(adapter.interpretResponse(unavailableResponse, bid)).to.deep.equal([]);
205
+ });
206
+
207
+ it('if response reflects availability, should equal result', function () {
208
+ expect(adapter.interpretResponse(availableResponse, bid)).to.deep.equal([result])
209
+ })
210
+ });
211
+ });
@@ -177,6 +177,16 @@ describe('YahooSSP Bid Adapter:', () => {
177
177
  expect(obj).to.be.an('object');
178
178
  });
179
179
 
180
+ describe('Validate basic properties', () => {
181
+ it('should define the correct bidder code', () => {
182
+ expect(spec.code).to.equal('yahoossp')
183
+ });
184
+
185
+ it('should define the correct vendor ID', () => {
186
+ expect(spec.gvlid).to.equal(25)
187
+ });
188
+ });
189
+
180
190
  describe('getUserSyncs()', () => {
181
191
  const IMAGE_PIXEL_URL = 'http://image-pixel.com/foo/bar?1234&baz=true';
182
192
  const IFRAME_ONE_URL = 'http://image-iframe.com/foo/bar?1234&baz=true';
@@ -0,0 +1,123 @@
1
+ import {bidderSettings, ScopedSettings} from '../../../../src/bidderSettings.js';
2
+ import {expect} from 'chai';
3
+ import * as prebidGlobal from '../../../../src/prebidGlobal';
4
+ import sinon from 'sinon';
5
+
6
+ describe('ScopedSettings', () => {
7
+ let data;
8
+ let settings;
9
+
10
+ beforeEach(() => {
11
+ settings = new ScopedSettings(() => data, 'fallback');
12
+ });
13
+
14
+ describe('get', () => {
15
+ it('should retrieve setting from scope', () => {
16
+ data = {
17
+ scope: {key: 'value'}
18
+ };
19
+ expect(settings.get('scope', 'key')).to.equal('value');
20
+ });
21
+
22
+ it('should fallback to fallback scope', () => {
23
+ data = {
24
+ fallback: {
25
+ key: 'value'
26
+ }
27
+ };
28
+ expect(settings.get('scope', 'key')).to.equal('value');
29
+ });
30
+
31
+ it('should retrieve from default scope if scope is null', () => {
32
+ data = {
33
+ fallback: {
34
+ key: 'value'
35
+ }
36
+ };
37
+
38
+ expect(settings.get(null, 'key')).to.equal('value');
39
+ });
40
+
41
+ it('should not fall back if own setting has a falsy value', () => {
42
+ data = {
43
+ scope: {
44
+ key: false,
45
+ },
46
+ fallback: {
47
+ key: true
48
+ }
49
+ }
50
+ expect(settings.get('scope', 'key')).to.equal(false);
51
+ })
52
+ });
53
+
54
+ describe('getOwn', () => {
55
+ it('should not fall back to default scope', () => {
56
+ data = {
57
+ fallback: {
58
+ key: 'value'
59
+ }
60
+ };
61
+ expect(settings.getOwn('missing', 'key')).to.be.undefined;
62
+ });
63
+
64
+ it('should use default if scope is null', () => {
65
+ data = {
66
+ fallback: {
67
+ key: 'value'
68
+ }
69
+ };
70
+ expect(settings.getOwn(null, 'key')).to.equal('value');
71
+ });
72
+ });
73
+
74
+ describe('getScopes', () => {
75
+ it('should return all top-level keys except the default scope', () => {
76
+ data = {
77
+ fallback: {},
78
+ scope1: {},
79
+ scope2: {},
80
+ };
81
+ expect(settings.getScopes()).to.have.members(['scope1', 'scope2']);
82
+ });
83
+ });
84
+
85
+ describe('settingsFor', () => {
86
+ it('should merge with default scope', () => {
87
+ data = {
88
+ fallback: {
89
+ dkey: 'value'
90
+ },
91
+ scope: {
92
+ skey: 'value'
93
+ }
94
+ }
95
+ expect(settings.settingsFor('scope')).to.eql({
96
+ dkey: 'value',
97
+ skey: 'value'
98
+ })
99
+ })
100
+ });
101
+ });
102
+
103
+ describe('bidderSettings', () => {
104
+ let sandbox;
105
+ beforeEach(() => {
106
+ sandbox = sinon.sandbox.create();
107
+ sandbox.stub(prebidGlobal, 'getGlobal').returns({
108
+ bidderSettings: {
109
+ scope: {
110
+ key: 'value'
111
+ }
112
+ }
113
+ });
114
+ })
115
+
116
+ afterEach(() => {
117
+ sandbox.restore();
118
+ })
119
+
120
+ it('should fetch data from getGlobal().bidderSettings', () => {
121
+ expect(bidderSettings.get('scope', 'key')).to.equal('value');
122
+ })
123
+ });
@@ -16,6 +16,7 @@ import * as auctionModule from 'src/auction.js';
16
16
  import { registerBidder } from 'src/adapters/bidderFactory.js';
17
17
  import { _sendAdToCreative } from 'src/secureCreatives.js';
18
18
  import find from 'core-js-pure/features/array/find.js';
19
+ import {synchronizePromise} from '../../helpers/syncPromise.js';
19
20
 
20
21
  var assert = require('chai').assert;
21
22
  var expect = require('chai').expect;
@@ -190,13 +191,16 @@ window.apntag = {
190
191
  }
191
192
 
192
193
  describe('Unit: Prebid Module', function () {
193
- let bidExpiryStub;
194
+ let bidExpiryStub, promiseSandbox;
194
195
  beforeEach(function () {
196
+ promiseSandbox = sinon.createSandbox();
197
+ synchronizePromise(promiseSandbox);
195
198
  bidExpiryStub = sinon.stub(filters, 'isBidNotExpired').callsFake(() => true);
196
199
  configObj.setConfig({ useBidCache: true });
197
200
  });
198
201
 
199
202
  afterEach(function() {
203
+ promiseSandbox.restore();
200
204
  $$PREBID_GLOBAL$$.adUnits = [];
201
205
  bidExpiryStub.restore();
202
206
  configObj.setConfig({ useBidCache: false });
@@ -1002,12 +1006,7 @@ describe('Unit: Prebid Module', function () {
1002
1006
  adUnitCode: config.adUnitCodes[0],
1003
1007
  };
1004
1008
 
1005
- const event = {
1006
- source: { postMessage: sinon.stub() },
1007
- origin: 'origin.sf.com'
1008
- };
1009
-
1010
- _sendAdToCreative(mockAdObject, event);
1009
+ _sendAdToCreative(mockAdObject, sinon.stub());
1011
1010
 
1012
1011
  expect(slots[0].spyGetSlotElementId.called).to.equal(false);
1013
1012
  expect(slots[1].spyGetSlotElementId.called).to.equal(true);
@@ -1135,13 +1134,15 @@ describe('Unit: Prebid Module', function () {
1135
1134
  height: 0
1136
1135
  }
1137
1136
  },
1138
- getElementsByTagName: sinon.stub()
1137
+ getElementsByTagName: sinon.stub(),
1138
+ querySelector: sinon.stub()
1139
1139
  };
1140
1140
 
1141
1141
  elStub = {
1142
1142
  insertBefore: sinon.stub()
1143
1143
  };
1144
1144
  doc.getElementsByTagName.returns([elStub]);
1145
+ doc.querySelector.returns(elStub);
1145
1146
 
1146
1147
  spyLogError = sinon.spy(utils, 'logError');
1147
1148
  spyLogMessage = sinon.spy(utils, 'logMessage');
@@ -1852,11 +1853,23 @@ describe('Unit: Prebid Module', function () {
1852
1853
  pos: 2
1853
1854
  }
1854
1855
  }
1856
+ },
1857
+ {
1858
+ code: 'test6',
1859
+ bids: [],
1860
+ sizes: [300, 250],
1861
+ mediaTypes: {
1862
+ banner: {
1863
+ sizes: [300, 250],
1864
+ pos: 0
1865
+ }
1866
+ }
1855
1867
  }];
1856
1868
  $$PREBID_GLOBAL$$.requestBids({
1857
1869
  adUnits: adUnit
1858
1870
  });
1859
1871
  expect(auctionArgs.adUnits[0].mediaTypes.banner.pos).to.equal(2);
1872
+ expect(auctionArgs.adUnits[1].mediaTypes.banner.pos).to.equal(0);
1860
1873
  });
1861
1874
  });
1862
1875
 
@@ -1,6 +1,7 @@
1
1
  import {
2
- _sendAdToCreative, receiveMessage
2
+ _sendAdToCreative, getReplier, receiveMessage
3
3
  } from 'src/secureCreatives.js';
4
+ import * as secureCreatives from 'src/secureCreatives.js';
4
5
  import * as utils from 'src/utils.js';
5
6
  import {getAdUnits, getBidRequests, getBidResponses} from 'test/fixtures/fixtures.js';
6
7
  import {auctionManager} from 'src/auctionManager.js';
@@ -9,12 +10,51 @@ import * as native from 'src/native.js';
9
10
  import {fireNativeTrackers, getAllAssetsMessage} from 'src/native.js';
10
11
  import events from 'src/events.js';
11
12
  import { config as configObj } from 'src/config.js';
13
+ import 'src/prebid.js';
12
14
 
13
15
  import { expect } from 'chai';
14
16
 
15
17
  var CONSTANTS = require('src/constants.json');
16
18
 
17
19
  describe('secureCreatives', () => {
20
+ function makeEvent(ev) {
21
+ return Object.assign({origin: 'mock-origin', ports: []}, ev)
22
+ }
23
+
24
+ describe('getReplier', () => {
25
+ it('should use source.postMessage if no MessagePort is available', () => {
26
+ const ev = {
27
+ ports: [],
28
+ source: {
29
+ postMessage: sinon.spy()
30
+ },
31
+ origin: 'mock-origin'
32
+ };
33
+ getReplier(ev)('test');
34
+ sinon.assert.calledWith(ev.source.postMessage, JSON.stringify('test'));
35
+ });
36
+
37
+ it('should use MesagePort.postMessage if available', () => {
38
+ const ev = {
39
+ ports: [{
40
+ postMessage: sinon.spy()
41
+ }]
42
+ }
43
+ getReplier(ev)('test');
44
+ sinon.assert.calledWith(ev.ports[0].postMessage, JSON.stringify('test'));
45
+ });
46
+
47
+ it('should throw if origin is null and no MessagePort is available', () => {
48
+ const ev = {
49
+ origin: null,
50
+ ports: [],
51
+ postMessage: sinon.spy()
52
+ }
53
+ const reply = getReplier(ev);
54
+ expect(() => reply('test')).to.throw();
55
+ });
56
+ });
57
+
18
58
  describe('_sendAdToCreative', () => {
19
59
  beforeEach(function () {
20
60
  sinon.stub(utils, 'logError');
@@ -40,14 +80,10 @@ describe('secureCreatives', () => {
40
80
  cpm: '1.00',
41
81
  adUnitCode: 'some_dom_id'
42
82
  };
43
- const event = {
44
- source: { postMessage: sinon.stub() },
45
- origin: 'origin.sf.com'
46
- };
47
-
48
- _sendAdToCreative(mockAdObject, event);
49
- expect(JSON.parse(event.source.postMessage.args[0][0]).ad).to.equal('<script src="http://prebid.org/creative/1.00"></script>');
50
- expect(JSON.parse(event.source.postMessage.args[0][0]).adUrl).to.equal('http://creative.prebid.org/1.00');
83
+ const reply = sinon.spy();
84
+ _sendAdToCreative(mockAdObject, reply);
85
+ expect(reply.args[0][0].ad).to.equal('<script src="http://prebid.org/creative/1.00"></script>');
86
+ expect(reply.args[0][0].adUrl).to.equal('http://creative.prebid.org/1.00');
51
87
  window.googletag = oldVal;
52
88
  window.apntag = oldapntag;
53
89
  });
@@ -141,9 +177,9 @@ describe('secureCreatives', () => {
141
177
  message: 'Prebid Request'
142
178
  };
143
179
 
144
- const ev = {
145
- data: JSON.stringify(data)
146
- };
180
+ const ev = makeEvent({
181
+ data: JSON.stringify(data),
182
+ });
147
183
 
148
184
  receiveMessage(ev);
149
185
 
@@ -168,9 +204,9 @@ describe('secureCreatives', () => {
168
204
  message: 'Prebid Request'
169
205
  };
170
206
 
171
- const ev = {
207
+ const ev = makeEvent({
172
208
  data: JSON.stringify(data)
173
- };
209
+ });
174
210
 
175
211
  receiveMessage(ev);
176
212
 
@@ -209,9 +245,9 @@ describe('secureCreatives', () => {
209
245
  message: 'Prebid Request'
210
246
  };
211
247
 
212
- const ev = {
248
+ const ev = makeEvent({
213
249
  data: JSON.stringify(data)
214
- };
250
+ });
215
251
 
216
252
  receiveMessage(ev);
217
253
 
@@ -237,6 +273,38 @@ describe('secureCreatives', () => {
237
273
 
238
274
  configObj.setConfig({'auctionOptions': {}});
239
275
  });
276
+
277
+ it('should emit AD_RENDER_FAILED if requested missing adId', () => {
278
+ const ev = makeEvent({
279
+ data: JSON.stringify({
280
+ message: 'Prebid Request',
281
+ adId: 'missing'
282
+ })
283
+ });
284
+ receiveMessage(ev);
285
+ sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.AD_RENDER_FAILED, sinon.match({
286
+ reason: CONSTANTS.AD_RENDER_FAILED_REASON.CANNOT_FIND_AD,
287
+ adId: 'missing'
288
+ }));
289
+ });
290
+
291
+ it('should emit AD_RENDER_FAILED if creative can\'t be sent to rendering frame', () => {
292
+ pushBidResponseToAuction({});
293
+ const ev = makeEvent({
294
+ source: {
295
+ postMessage: sinon.stub().callsFake(() => { throw new Error(); })
296
+ },
297
+ data: JSON.stringify({
298
+ message: 'Prebid Request',
299
+ adId: bidId
300
+ })
301
+ });
302
+ receiveMessage(ev)
303
+ sinon.assert.calledWith(stubEmit, CONSTANTS.EVENTS.AD_RENDER_FAILED, sinon.match({
304
+ reason: CONSTANTS.AD_RENDER_FAILED_REASON.EXCEPTION,
305
+ adId: bidId
306
+ }));
307
+ });
240
308
  });
241
309
 
242
310
  describe('Prebid Native', function() {
@@ -249,13 +317,13 @@ describe('secureCreatives', () => {
249
317
  action: 'allAssetRequest'
250
318
  };
251
319
 
252
- const ev = {
320
+ const ev = makeEvent({
253
321
  data: JSON.stringify(data),
254
322
  source: {
255
323
  postMessage: sinon.stub()
256
324
  },
257
325
  origin: 'any origin'
258
- };
326
+ });
259
327
 
260
328
  receiveMessage(ev);
261
329
 
@@ -278,13 +346,13 @@ describe('secureCreatives', () => {
278
346
  action: 'allAssetRequest'
279
347
  };
280
348
 
281
- const ev = {
349
+ const ev = makeEvent({
282
350
  data: JSON.stringify(data),
283
351
  source: {
284
352
  postMessage: sinon.stub()
285
353
  },
286
354
  origin: 'any origin'
287
- };
355
+ });
288
356
 
289
357
  receiveMessage(ev);
290
358
 
@@ -322,13 +390,13 @@ describe('secureCreatives', () => {
322
390
  action: 'allAssetRequest'
323
391
  };
324
392
 
325
- const ev = {
393
+ const ev = makeEvent({
326
394
  data: JSON.stringify(data),
327
395
  source: {
328
396
  postMessage: sinon.stub()
329
397
  },
330
398
  origin: 'any origin'
331
- };
399
+ });
332
400
 
333
401
  receiveMessage(ev);
334
402
 
@@ -366,13 +434,13 @@ describe('secureCreatives', () => {
366
434
  action: 'click',
367
435
  };
368
436
 
369
- const ev = {
437
+ const ev = makeEvent({
370
438
  data: JSON.stringify(data),
371
439
  source: {
372
440
  postMessage: sinon.stub()
373
441
  },
374
442
  origin: 'any origin'
375
- };
443
+ });
376
444
 
377
445
  receiveMessage(ev);
378
446
 
@@ -395,5 +463,56 @@ describe('secureCreatives', () => {
395
463
  expect(adResponse).to.have.property('status', CONSTANTS.BID_STATUS.RENDERED);
396
464
  });
397
465
  });
466
+
467
+ describe('Prebid Event', () => {
468
+ Object.entries({
469
+ 'unrendered': [false, (bid) => { delete bid.status; }],
470
+ 'rendered': [true, (bid) => { bid.status = CONSTANTS.BID_STATUS.RENDERED }]
471
+ }).forEach(([test, [shouldEmit, prepBid]]) => {
472
+ describe(`for ${test} bids`, () => {
473
+ beforeEach(() => {
474
+ prepBid(adResponse);
475
+ pushBidResponseToAuction(adResponse);
476
+ });
477
+
478
+ it(`should${shouldEmit ? ' ' : ' not '}emit AD_RENDER_FAILED`, () => {
479
+ const event = makeEvent({
480
+ data: JSON.stringify({
481
+ message: 'Prebid Event',
482
+ event: CONSTANTS.EVENTS.AD_RENDER_FAILED,
483
+ adId: bidId,
484
+ info: {
485
+ reason: 'Fail reason',
486
+ message: 'Fail message',
487
+ },
488
+ })
489
+ });
490
+ receiveMessage(event);
491
+ expect(stubEmit.calledWith(CONSTANTS.EVENTS.AD_RENDER_FAILED, {
492
+ adId: bidId,
493
+ bid: adResponse,
494
+ reason: 'Fail reason',
495
+ message: 'Fail message'
496
+ })).to.equal(shouldEmit);
497
+ });
498
+
499
+ it(`should${shouldEmit ? ' ' : ' not '}emit AD_RENDER_SUCCEEDED`, () => {
500
+ const event = makeEvent({
501
+ data: JSON.stringify({
502
+ message: 'Prebid Event',
503
+ event: CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED,
504
+ adId: bidId,
505
+ })
506
+ });
507
+ receiveMessage(event);
508
+ expect(stubEmit.calledWith(CONSTANTS.EVENTS.AD_RENDER_SUCCEEDED, {
509
+ adId: bidId,
510
+ bid: adResponse,
511
+ doc: null
512
+ })).to.equal(shouldEmit);
513
+ });
514
+ });
515
+ });
516
+ });
398
517
  });
399
518
  });