prebid.js 7.46.0 → 7.48.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 (195) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/33acrossIdSystem.js +1 -1
  3. package/dist/ablidaBidAdapter.js +1 -1
  4. package/dist/adagioBidAdapter.js +1 -1
  5. package/dist/adbookpspBidAdapter.js +1 -1
  6. package/dist/adgenerationBidAdapter.js +1 -1
  7. package/dist/admaticBidAdapter.js +1 -1
  8. package/dist/adrelevantisBidAdapter.js +1 -1
  9. package/dist/adrinoBidAdapter.js +1 -1
  10. package/dist/adtrgtmeBidAdapter.js +1 -1
  11. package/dist/adxcgBidAdapter.js +1 -1
  12. package/dist/adyoulikeBidAdapter.js +1 -1
  13. package/dist/ajaBidAdapter.js +1 -1
  14. package/dist/amxBidAdapter.js +1 -1
  15. package/dist/amxIdSystem.js +1 -1
  16. package/dist/appierAnalyticsAdapter.js +1 -1
  17. package/dist/appnexusBidAdapter.js +1 -1
  18. package/dist/asoBidAdapter.js +1 -1
  19. package/dist/axonixBidAdapter.js +1 -1
  20. package/dist/bidglassBidAdapter.js +1 -1
  21. package/dist/big-richmediaBidAdapter.js +1 -1
  22. package/dist/bridgewellBidAdapter.js +1 -1
  23. package/dist/brightMountainMediaBidAdapter.js +1 -1
  24. package/dist/carodaBidAdapter.js +1 -1
  25. package/dist/chtnwBidAdapter.js +1 -1
  26. package/dist/concertBidAdapter.js +1 -1
  27. package/dist/connectIdSystem.js +1 -1
  28. package/dist/connectadBidAdapter.js +1 -1
  29. package/dist/consumableBidAdapter.js +1 -1
  30. package/dist/conversantAnalyticsAdapter.js +1 -1
  31. package/dist/conversantBidAdapter.js +1 -1
  32. package/dist/craftBidAdapter.js +1 -1
  33. package/dist/criteoBidAdapter.js +1 -1
  34. package/dist/criteoIdSystem.js +1 -1
  35. package/dist/cwireBidAdapter.js +1 -1
  36. package/dist/dependencies.json +4 -0
  37. package/dist/dspxBidAdapter.js +1 -1
  38. package/dist/emtvBidAdapter.js +1 -0
  39. package/dist/eplanningBidAdapter.js +1 -1
  40. package/dist/feedadBidAdapter.js +1 -1
  41. package/dist/finativeBidAdapter.js +1 -1
  42. package/dist/freewheel-sspBidAdapter.js +1 -1
  43. package/dist/glimpseBidAdapter.js +1 -1
  44. package/dist/gmosspBidAdapter.js +1 -1
  45. package/dist/goldbachBidAdapter.js +1 -1
  46. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  47. package/dist/greenbidsRtdProvider.js +1 -0
  48. package/dist/gridBidAdapter.js +1 -1
  49. package/dist/gumgumBidAdapter.js +1 -1
  50. package/dist/h12mediaBidAdapter.js +1 -1
  51. package/dist/id5IdSystem.js +1 -1
  52. package/dist/impactifyBidAdapter.js +1 -1
  53. package/dist/improvedigitalBidAdapter.js +1 -1
  54. package/dist/inmarBidAdapter.js +1 -1
  55. package/dist/insticatorBidAdapter.js +1 -1
  56. package/dist/iqmBidAdapter.js +1 -1
  57. package/dist/ixBidAdapter.js +1 -1
  58. package/dist/justpremiumBidAdapter.js +1 -1
  59. package/dist/kargoBidAdapter.js +1 -1
  60. package/dist/konduitAnalyticsAdapter.js +1 -1
  61. package/dist/kueezBidAdapter.js +1 -1
  62. package/dist/kueezRtbBidAdapter.js +1 -1
  63. package/dist/kulturemediaBidAdapter.js +1 -1
  64. package/dist/lassoBidAdapter.js +1 -1
  65. package/dist/lifestreetBidAdapter.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/magniteAnalyticsAdapter.js +1 -1
  70. package/dist/malltvAnalyticsAdapter.js +1 -1
  71. package/dist/marsmediaBidAdapter.js +1 -1
  72. package/dist/mediafuseBidAdapter.js +1 -1
  73. package/dist/mediasquareBidAdapter.js +1 -1
  74. package/dist/mgidBidAdapter.js +1 -1
  75. package/dist/minutemediaBidAdapter.js +1 -1
  76. package/dist/minutemediaplusBidAdapter.js +1 -1
  77. package/dist/missenaBidAdapter.js +1 -1
  78. package/dist/nextMillenniumBidAdapter.js +1 -1
  79. package/dist/nexx360BidAdapter.js +1 -1
  80. package/dist/not-for-prod/prebid.js +142 -139
  81. package/dist/oguryBidAdapter.js +1 -1
  82. package/dist/onetagBidAdapter.js +1 -1
  83. package/dist/ooloAnalyticsAdapter.js +1 -1
  84. package/dist/optidigitalBidAdapter.js +1 -1
  85. package/dist/orbitsoftBidAdapter.js +1 -1
  86. package/dist/outbrainBidAdapter.js +1 -1
  87. package/dist/parrableIdSystem.js +1 -1
  88. package/dist/pixfutureBidAdapter.js +1 -1
  89. package/dist/prebid-core.js +1 -1
  90. package/dist/publinkIdSystem.js +1 -1
  91. package/dist/pubmaticBidAdapter.js +1 -1
  92. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  93. package/dist/pxyzBidAdapter.js +1 -1
  94. package/dist/quantcastBidAdapter.js +1 -1
  95. package/dist/radsBidAdapter.js +1 -1
  96. package/dist/readpeakBidAdapter.js +1 -1
  97. package/dist/relaidoBidAdapter.js +1 -1
  98. package/dist/relevantdigitalBidAdapter.js +1 -0
  99. package/dist/rhythmoneBidAdapter.js +1 -1
  100. package/dist/riseBidAdapter.js +1 -1
  101. package/dist/rtbhouseBidAdapter.js +1 -1
  102. package/dist/rubiconAnalyticsAdapter.js +1 -1
  103. package/dist/rubiconBidAdapter.js +1 -1
  104. package/dist/seedingAllianceBidAdapter.js +1 -1
  105. package/dist/seedtagBidAdapter.js +1 -1
  106. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  107. package/dist/sharethroughBidAdapter.js +1 -1
  108. package/dist/shinezBidAdapter.js +1 -1
  109. package/dist/smaatoBidAdapter.js +1 -1
  110. package/dist/smartadserverBidAdapter.js +1 -1
  111. package/dist/smartxBidAdapter.js +1 -1
  112. package/dist/smilewantedBidAdapter.js +1 -1
  113. package/dist/sonobiBidAdapter.js +1 -1
  114. package/dist/sovrnAnalyticsAdapter.js +1 -1
  115. package/dist/sovrnBidAdapter.js +1 -1
  116. package/dist/sspBCBidAdapter.js +1 -1
  117. package/dist/stvBidAdapter.js +1 -1
  118. package/dist/sublimeBidAdapter.js +1 -1
  119. package/dist/synacormediaBidAdapter.js +1 -1
  120. package/dist/targetVideoBidAdapter.js +1 -1
  121. package/dist/teadsBidAdapter.js +1 -1
  122. package/dist/trionBidAdapter.js +1 -1
  123. package/dist/tripleliftBidAdapter.js +1 -1
  124. package/dist/ttdBidAdapter.js +1 -1
  125. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  126. package/dist/uid2IdSystem.js +1 -1
  127. package/dist/underdogmediaBidAdapter.js +1 -1
  128. package/dist/undertoneBidAdapter.js +1 -1
  129. package/dist/userId.js +1 -1
  130. package/dist/vdoaiBidAdapter.js +1 -1
  131. package/dist/vidazooBidAdapter.js +1 -1
  132. package/dist/videobyteBidAdapter.js +1 -1
  133. package/dist/vidoomyBidAdapter.js +1 -1
  134. package/dist/visxBidAdapter.js +1 -1
  135. package/dist/vuukleBidAdapter.js +1 -1
  136. package/dist/widespaceBidAdapter.js +1 -1
  137. package/dist/winrBidAdapter.js +1 -1
  138. package/dist/wipesBidAdapter.js +1 -1
  139. package/dist/yahoosspBidAdapter.js +1 -1
  140. package/dist/yieldmoBidAdapter.js +1 -1
  141. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  142. package/dist/yieldoneBidAdapter.js +1 -1
  143. package/modules/ablidaBidAdapter.js +4 -5
  144. package/modules/admaticBidAdapter.js +32 -5
  145. package/modules/adrinoBidAdapter.js +11 -4
  146. package/modules/axonixBidAdapter.js +6 -6
  147. package/modules/connectIdSystem.js +5 -2
  148. package/modules/criteoBidAdapter.js +3 -5
  149. package/modules/criteoIdSystem.js +27 -14
  150. package/modules/dspxBidAdapter.js +2 -3
  151. package/modules/emtvBidAdapter.js +211 -0
  152. package/modules/emtvBidAdapter.md +79 -0
  153. package/modules/freewheel-sspBidAdapter.js +32 -7
  154. package/modules/greenbidsRtdProvider.js +110 -0
  155. package/modules/greenbidsRtdProvider.md +65 -0
  156. package/modules/impactifyBidAdapter.js +0 -1
  157. package/modules/iqmBidAdapter.js +1 -2
  158. package/modules/missenaBidAdapter.js +1 -1
  159. package/modules/nextMillenniumBidAdapter.js +2 -0
  160. package/modules/orbitsoftBidAdapter.js +1 -2
  161. package/modules/radsBidAdapter.js +3 -4
  162. package/modules/relevantdigitalBidAdapter.js +198 -0
  163. package/modules/relevantdigitalBidAdapter.md +117 -0
  164. package/modules/rtbhouseBidAdapter.js +9 -12
  165. package/modules/sovrnBidAdapter.js +4 -0
  166. package/modules/stvBidAdapter.js +4 -5
  167. package/modules/tripleliftBidAdapter.js +14 -3
  168. package/modules/ttdBidAdapter.js +73 -71
  169. package/modules/underdogmediaBidAdapter.js +9 -12
  170. package/modules/userId/index.js +1 -1
  171. package/modules/vdoaiBidAdapter.js +2 -3
  172. package/modules/vidoomyBidAdapter.js +19 -6
  173. package/modules/vidoomyBidAdapter.md +12 -2
  174. package/modules/wipesBidAdapter.js +2 -3
  175. package/modules/yieldmoBidAdapter.js +2 -2
  176. package/modules/yieldoneBidAdapter.js +3 -4
  177. package/package.json +1 -1
  178. package/test/spec/modules/adlooxAdServerVideo_spec.js +18 -35
  179. package/test/spec/modules/admaticBidAdapter_spec.js +164 -11
  180. package/test/spec/modules/adrinoBidAdapter_spec.js +50 -2
  181. package/test/spec/modules/connectIdSystem_spec.js +4 -4
  182. package/test/spec/modules/criteoBidAdapter_spec.js +56 -0
  183. package/test/spec/modules/criteoIdSystem_spec.js +99 -9
  184. package/test/spec/modules/emtvBidAdapter_spec.js +400 -0
  185. package/test/spec/modules/freewheel-sspBidAdapter_spec.js +31 -2
  186. package/test/spec/modules/greenbidsRtdProvider_spec.js +210 -0
  187. package/test/spec/modules/relevantdigitalBidAdapter_spec.js +295 -0
  188. package/test/spec/modules/rtbhouseBidAdapter_spec.js +24 -2
  189. package/test/spec/modules/sovrnBidAdapter_spec.js +65 -0
  190. package/test/spec/modules/tripleliftBidAdapter_spec.js +53 -8
  191. package/test/spec/modules/ttdBidAdapter_spec.js +20 -0
  192. package/test/spec/modules/vidoomyBidAdapter_spec.js +49 -0
  193. package/test/spec/modules/yieldmoBidAdapter_spec.js +2 -2
  194. package/test/spec/ortbConverter/userId_spec.js +12 -0
  195. package/test/spec/modules/realvuAnalyticsAdapter_spec.js +0 -189
@@ -0,0 +1,210 @@
1
+ import { expect } from 'chai';
2
+ import sinon from 'sinon';
3
+ import {
4
+ deepClone,
5
+ } from '../../../src/utils.js';
6
+ import {
7
+ greenbidsSubmodule
8
+ } from 'modules/greenbidsRtdProvider.js';
9
+
10
+ describe('greenbidsRtdProvider', () => {
11
+ let server;
12
+
13
+ beforeEach(() => {
14
+ server = sinon.createFakeServer();
15
+ });
16
+
17
+ afterEach(() => {
18
+ server.restore();
19
+ });
20
+
21
+ const endPoint = 'europe-west1-greenbids-357713.cloudfunctions.net';
22
+
23
+ const SAMPLE_MODULE_CONFIG = {
24
+ params: {
25
+ pbuid: '12345',
26
+ timeout: 200,
27
+ targetTPR: 0.95
28
+ }
29
+ };
30
+
31
+ const SAMPLE_REQUEST_BIDS_CONFIG_OBJ = {
32
+ adUnits: [
33
+ {
34
+ code: 'adUnit1',
35
+ bids: [
36
+ { bidder: 'appnexus', params: {} },
37
+ { bidder: 'rubicon', params: {} },
38
+ { bidder: 'ix', params: {} }
39
+ ]
40
+ },
41
+ {
42
+ code: 'adUnit2',
43
+ bids: [
44
+ { bidder: 'appnexus', params: {} },
45
+ { bidder: 'rubicon', params: {} },
46
+ { bidder: 'openx', params: {} }
47
+ ]
48
+ }]
49
+ };
50
+
51
+ const SAMPLE_RESPONSE_ADUNITS = [
52
+ {
53
+ code: 'adUnit1',
54
+ bidders: {
55
+ 'appnexus': true,
56
+ 'rubicon': false,
57
+ 'ix': true
58
+ }
59
+ },
60
+ {
61
+ code: 'adUnit2',
62
+ bidders: {
63
+ 'appnexus': false,
64
+ 'rubicon': true,
65
+ 'openx': true
66
+ }
67
+ }];
68
+
69
+ describe('init', () => {
70
+ it('should return true and set rtdOptions if pbuid is present', () => {
71
+ const result = greenbidsSubmodule.init(SAMPLE_MODULE_CONFIG);
72
+ expect(result).to.be.true;
73
+ });
74
+
75
+ it('should return false if pbuid is not present', () => {
76
+ const result = greenbidsSubmodule.init({ params: {} });
77
+ expect(result).to.be.false;
78
+ });
79
+ });
80
+
81
+ describe('updateAdUnitsBasedOnResponse', () => {
82
+ it('should update ad units based on response', () => {
83
+ const adUnits = JSON.parse(JSON.stringify(SAMPLE_REQUEST_BIDS_CONFIG_OBJ.adUnits));
84
+ greenbidsSubmodule.updateAdUnitsBasedOnResponse(adUnits, SAMPLE_RESPONSE_ADUNITS);
85
+
86
+ expect(adUnits[0].bids).to.have.length(2);
87
+ expect(adUnits[1].bids).to.have.length(2);
88
+ });
89
+ });
90
+
91
+ describe('findMatchingAdUnit', () => {
92
+ it('should find matching ad unit by code', () => {
93
+ const matchingAdUnit = greenbidsSubmodule.findMatchingAdUnit(SAMPLE_RESPONSE_ADUNITS, 'adUnit1');
94
+ expect(matchingAdUnit).to.deep.equal(SAMPLE_RESPONSE_ADUNITS[0]);
95
+ });
96
+ it('should return undefined if no matching ad unit is found', () => {
97
+ const matchingAdUnit = greenbidsSubmodule.findMatchingAdUnit(SAMPLE_RESPONSE_ADUNITS, 'nonexistent');
98
+ expect(matchingAdUnit).to.be.undefined;
99
+ });
100
+ });
101
+
102
+ describe('removeFalseBidders', () => {
103
+ it('should remove bidders with false value', () => {
104
+ const adUnit = JSON.parse(JSON.stringify(SAMPLE_REQUEST_BIDS_CONFIG_OBJ.adUnits[0]));
105
+ const matchingAdUnit = SAMPLE_RESPONSE_ADUNITS[0];
106
+ greenbidsSubmodule.removeFalseBidders(adUnit, matchingAdUnit);
107
+ expect(adUnit.bids).to.have.length(2);
108
+ expect(adUnit.bids.map((bid) => bid.bidder)).to.not.include('rubicon');
109
+ });
110
+ });
111
+
112
+ describe('getFalseBidders', () => {
113
+ it('should return an array of false bidders', () => {
114
+ const bidders = {
115
+ appnexus: true,
116
+ rubicon: false,
117
+ ix: true,
118
+ openx: false
119
+ };
120
+ const falseBidders = greenbidsSubmodule.getFalseBidders(bidders);
121
+ expect(falseBidders).to.have.length(2);
122
+ expect(falseBidders).to.include('rubicon');
123
+ expect(falseBidders).to.include('openx');
124
+ });
125
+ });
126
+
127
+ describe('getBidRequestData', () => {
128
+ it('Callback is called if the server responds a 200 within the time limit', (done) => {
129
+ let requestBids = deepClone(SAMPLE_REQUEST_BIDS_CONFIG_OBJ);
130
+ let callback = sinon.stub();
131
+
132
+ greenbidsSubmodule.getBidRequestData(requestBids, callback, SAMPLE_MODULE_CONFIG);
133
+
134
+ setTimeout(() => {
135
+ server.requests[0].respond(
136
+ 200,
137
+ {'Content-Type': 'application/json'},
138
+ JSON.stringify(SAMPLE_RESPONSE_ADUNITS)
139
+ );
140
+ done();
141
+ }, 50);
142
+
143
+ setTimeout(() => {
144
+ const requestUrl = new URL(server.requests[0].url);
145
+ expect(requestUrl.host).to.be.eq(endPoint);
146
+ expect(requestBids.adUnits[0].bids).to.have.length(2);
147
+ expect(requestBids.adUnits[0].bids.map((bid) => bid.bidder)).to.not.include('rubicon');
148
+ expect(requestBids.adUnits[0].bids.map((bid) => bid.bidder)).to.include('ix');
149
+ expect(requestBids.adUnits[0].bids.map((bid) => bid.bidder)).to.include('appnexus');
150
+ expect(requestBids.adUnits[1].bids).to.have.length(2);
151
+ expect(requestBids.adUnits[1].bids.map((bid) => bid.bidder)).to.not.include('appnexus');
152
+ expect(requestBids.adUnits[1].bids.map((bid) => bid.bidder)).to.include('rubicon');
153
+ expect(requestBids.adUnits[1].bids.map((bid) => bid.bidder)).to.include('openx');
154
+ expect(callback.calledOnce).to.be.true;
155
+ }, 60);
156
+ });
157
+ });
158
+
159
+ describe('getBidRequestData', () => {
160
+ it('Nothing changes if the server times out but still the callback is called', (done) => {
161
+ let requestBids = deepClone(SAMPLE_REQUEST_BIDS_CONFIG_OBJ);
162
+ let callback = sinon.stub();
163
+
164
+ greenbidsSubmodule.getBidRequestData(requestBids, callback, SAMPLE_MODULE_CONFIG);
165
+
166
+ setTimeout(() => {
167
+ server.requests[0].respond(
168
+ 200,
169
+ {'Content-Type': 'application/json'},
170
+ JSON.stringify(SAMPLE_RESPONSE_ADUNITS)
171
+ );
172
+ done();
173
+ }, 300);
174
+
175
+ setTimeout(() => {
176
+ const requestUrl = new URL(server.requests[0].url);
177
+ expect(requestUrl.host).to.be.eq(endPoint);
178
+ expect(requestBids.adUnits[0].bids).to.have.length(3);
179
+ expect(requestBids.adUnits[1].bids).to.have.length(3);
180
+ expect(callback.calledOnce).to.be.true;
181
+ }, 200);
182
+ });
183
+ });
184
+
185
+ describe('getBidRequestData', () => {
186
+ it('callback is called if the server responds a 500 error within the time limit and no changes are made', (done) => {
187
+ let requestBids = deepClone(SAMPLE_REQUEST_BIDS_CONFIG_OBJ);
188
+ let callback = sinon.stub();
189
+
190
+ greenbidsSubmodule.getBidRequestData(requestBids, callback, SAMPLE_MODULE_CONFIG);
191
+
192
+ setTimeout(() => {
193
+ server.requests[0].respond(
194
+ 500,
195
+ {'Content-Type': 'application/json'},
196
+ JSON.stringify({'failure': 'fail'})
197
+ );
198
+ done();
199
+ }, 50);
200
+
201
+ setTimeout(() => {
202
+ const requestUrl = new URL(server.requests[0].url);
203
+ expect(requestUrl.host).to.be.eq(endPoint);
204
+ expect(requestBids.adUnits[0].bids).to.have.length(3);
205
+ expect(requestBids.adUnits[1].bids).to.have.length(3);
206
+ expect(callback.calledOnce).to.be.true;
207
+ }, 60);
208
+ });
209
+ });
210
+ });
@@ -0,0 +1,295 @@
1
+ import {spec, resetBidderConfigs} from 'modules/relevantdigitalBidAdapter.js';
2
+ import { parseUrl, deepClone } from 'src/utils.js';
3
+
4
+ const expect = require('chai').expect;
5
+
6
+ const PBS_HOST = 'dev-api.relevant-digital.com';
7
+ const PLACEMENT_ID = 'example_placement_id';
8
+ const ACCOUNT_ID = 'example_account_id';
9
+ const TEST_DOMAIN = 'example.com';
10
+ const TEST_PAGE = `https://${TEST_DOMAIN}/page.html`;
11
+
12
+ const BID_REQUEST =
13
+ {
14
+ 'bidder': 'relevantdigital',
15
+ 'params': {
16
+ 'placementId': PLACEMENT_ID,
17
+ 'accountId': ACCOUNT_ID,
18
+ 'pbsHost': PBS_HOST,
19
+ },
20
+ 'ortb2Imp': {
21
+ 'ext': {
22
+ 'tid': 'e13391ea-00f3-495d-99a6-d937990d73a9'
23
+ }
24
+ },
25
+ 'mediaTypes': {
26
+ 'banner': {
27
+ 'sizes': [
28
+ [
29
+ 300,
30
+ 250
31
+ ],
32
+ ]
33
+ }
34
+ },
35
+ 'adUnitCode': '/19968336/header-bid-tag-0',
36
+ 'transactionId': 'e13391ea-00f3-495d-99a6-d937990d73a9',
37
+ 'sizes': [
38
+ [
39
+ 300,
40
+ 250
41
+ ],
42
+ ],
43
+ 'bidId': '2d69406037a662',
44
+ 'bidderRequestId': '1decd098c76ed2',
45
+ 'auctionId': '251a6a36-a5c5-4b82-b2b3-538c148a29dd',
46
+ 'src': 'client',
47
+ 'metrics': {
48
+ 'requestBids.validate': 0.7,
49
+ 'requestBids.makeRequests': 2.9,
50
+ 'adapter.client.validate': 0.4,
51
+ 'adapters.client.relevantdigital.validate': 0.4
52
+ },
53
+ 'bidRequestsCount': 1,
54
+ 'bidderRequestsCount': 1,
55
+ 'bidderWinsCount': 0,
56
+ 'ortb2': {
57
+ 'site': {
58
+ 'page': TEST_PAGE,
59
+ 'domain': TEST_DOMAIN,
60
+ 'publisher': {
61
+ 'domain': 'relevant-digital.com'
62
+ }
63
+ },
64
+ 'device': {
65
+ 'w': 1848,
66
+ 'h': 1007,
67
+ 'dnt': 0,
68
+ 'ua': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
69
+ 'language': 'en',
70
+ 'sua': {
71
+ 'source': 2,
72
+ 'platform': {
73
+ 'brand': 'Linux',
74
+ 'version': [
75
+ '5',
76
+ '4',
77
+ '0'
78
+ ]
79
+ },
80
+ 'browsers': [
81
+ {
82
+ 'brand': 'Google Chrome',
83
+ 'version': [
84
+ '111',
85
+ '0',
86
+ '5563',
87
+ '146'
88
+ ]
89
+ },
90
+ ],
91
+ 'mobile': 0,
92
+ 'model': '',
93
+ 'bitness': '64',
94
+ 'architecture': 'x86'
95
+ }
96
+ }
97
+ }
98
+ };
99
+
100
+ const BIDDER_REQUEST = {
101
+ 'bidderCode': BID_REQUEST.bidder,
102
+ 'auctionId': BID_REQUEST.auctionId,
103
+ 'bidderRequestId': BID_REQUEST.bidderRequestId,
104
+ 'bids': [BID_REQUEST],
105
+ 'metrics': BID_REQUEST.metrics,
106
+ 'ortb2': BID_REQUEST.ortb2,
107
+ 'auctionStart': 1681224591370,
108
+ 'timeout': 1000,
109
+ 'refererInfo': {
110
+ 'reachedTop': true,
111
+ 'isAmp': false,
112
+ 'numIframes': 0,
113
+ 'stack': [
114
+ TEST_PAGE
115
+ ],
116
+ 'topmostLocation': TEST_PAGE,
117
+ 'location': TEST_PAGE,
118
+ 'canonicalUrl': null,
119
+ 'page': TEST_PAGE,
120
+ 'domain': TEST_DOMAIN,
121
+ 'ref': null,
122
+ 'legacy': {
123
+ 'reachedTop': true,
124
+ 'isAmp': false,
125
+ 'numIframes': 0,
126
+ 'stack': [
127
+ TEST_PAGE
128
+ ],
129
+ 'referer': TEST_PAGE,
130
+ 'canonicalUrl': null
131
+ }
132
+ },
133
+ 'start': 1681224591375
134
+ };
135
+
136
+ const BID_RESPONSE = {
137
+ 'seatbid': [
138
+ {
139
+ 'bid': [
140
+ {
141
+ 'id': '613673EF-A07C-4486-8EE9-3FC71A7DC73D',
142
+ 'impid': BID_REQUEST.bidId,
143
+ 'price': 10.76091063668997,
144
+ 'adm': '<html><a href="http://www.pubmatic.com" target="_blank"><img src ="https://stagingva.pubmatic.com:8443/image/300x250.jpg" /></a></html>',
145
+ 'adomain': [
146
+ 'www.addomain.com'
147
+ ],
148
+ 'iurl': 'http://localhost11',
149
+ 'crid': 'creative111',
150
+ 'w': 300,
151
+ 'h': 250,
152
+ 'ext': {
153
+ 'bidtype': 0,
154
+ 'dspid': 6,
155
+ 'origbidcpm': 1,
156
+ 'origbidcur': 'USD',
157
+ 'prebid': {
158
+ 'meta': {
159
+ 'adaptercode': 'pubmatic'
160
+ },
161
+ 'targeting': {
162
+ 'hb_bidder': 'pubmatic',
163
+ 'hb_cache_host': PBS_HOST,
164
+ 'hb_cache_path': '/analytics_cache/read',
165
+ 'hb_format': 'banner',
166
+ 'hb_pb': '10.70',
167
+ 'hb_size': '300x250'
168
+ },
169
+ 'type': 'banner',
170
+ 'video': {
171
+ 'duration': 0,
172
+ 'primary_category': ''
173
+ },
174
+ 'events': {
175
+ 'win': `https://${PBS_HOST}/event?t=win&b=fed970f7-4295-456d-a251-38013faab795&a=620523ae7f4bbe1691bbb815&bidder=pubmatic&ts=1678646619765`,
176
+ 'imp': `https://${PBS_HOST}/event?t=imp&b=fed970f7-4295-456d-a251-38013faab795&a=620523ae7f4bbe1691bbb815&bidder=pubmatic&ts=1678646619765`
177
+ },
178
+ 'bidid': 'fed970f7-4295-456d-a251-38013faab795'
179
+ }
180
+ }
181
+ }
182
+ ],
183
+ 'seat': 'pubmatic'
184
+ }
185
+ ],
186
+ 'cur': 'SEK',
187
+ 'ext': {
188
+ 'responsetimemillis': {
189
+ 'appnexus': 305,
190
+ 'pubmatic': 156
191
+ },
192
+ 'tmaxrequest': 750,
193
+ 'relevant': {
194
+ 'sync': [
195
+ { 'type': 'redirect', 'url': 'https://example1.com/sync' },
196
+ { 'type': 'redirect', 'url': 'https://example2.com/sync' },
197
+ ],
198
+ },
199
+ 'prebid': {
200
+ 'auctiontimestamp': 1678646619765,
201
+ 'passthrough': {
202
+ 'relevant': {
203
+ 'bidder': spec.code
204
+ }
205
+ }
206
+ }
207
+ }
208
+ };
209
+
210
+ const S2S_RESPONSE_BIDDER = BID_RESPONSE.seatbid[0].seat;
211
+
212
+ const resetAndBuildRequest = (params) => {
213
+ resetBidderConfigs();
214
+ const bidRequest = {
215
+ ...BID_REQUEST,
216
+ params: {
217
+ ...BID_REQUEST.params,
218
+ ...params,
219
+ },
220
+ };
221
+ return spec.buildRequests([bidRequest], BIDDER_REQUEST);
222
+ };
223
+
224
+ describe('Relevant Digital Bid Adaper', function () {
225
+ describe('buildRequests', () => {
226
+ const [request] = resetAndBuildRequest();
227
+ const {data, url} = request
228
+ it('should give the correct URL', () => {
229
+ expect(url).equal(`https://${PBS_HOST}/openrtb2/auction`);
230
+ });
231
+ it('should set the correct stored request ids', () => {
232
+ expect(data.ext.prebid.storedrequest.id).equal(ACCOUNT_ID);
233
+ expect(data.imp[0].ext.prebid.storedrequest.id).equal(PLACEMENT_ID);
234
+ });
235
+ it('should include bidder code in passthrough object', () => {
236
+ expect(data.ext.prebid.passthrough.relevant.bidder).equal(spec.code);
237
+ });
238
+ it('should set tmax to something below the timeout', () => {
239
+ expect(data.tmax).be.greaterThan(0);
240
+ expect(data.tmax).be.lessThan(BIDDER_REQUEST.timeout)
241
+ });
242
+ });
243
+ describe('interpreteResponse', () => {
244
+ const [request] = resetAndBuildRequest();
245
+ const [bid] = spec.interpretResponse({ body: BID_RESPONSE }, request);
246
+ it('should not have S2S bidder\'s bidder code', () => {
247
+ expect(bid.bidderCode).not.equal(S2S_RESPONSE_BIDDER);
248
+ });
249
+ it('should return the right creative content', () => {
250
+ const respBid = BID_RESPONSE.seatbid[0].bid[0];
251
+ expect(bid.cpm).equal(respBid.price);
252
+ expect(bid.ad).equal(respBid.adm);
253
+ expect(bid.width).equal(respBid.w);
254
+ expect(bid.height).equal(respBid.h);
255
+ });
256
+ });
257
+ describe('interpreteResponse with useSourceBidderCode', () => {
258
+ const [request] = resetAndBuildRequest({ useSourceBidderCode: true });
259
+ const [bid] = spec.interpretResponse({ body: BID_RESPONSE }, request);
260
+ it('should have S2S bidder\'s code', () => {
261
+ expect(bid.bidderCode).equal(S2S_RESPONSE_BIDDER);
262
+ });
263
+ });
264
+ describe('getUserSyncs with iframeEnabled', () => {
265
+ resetAndBuildRequest()
266
+ const allSyncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: BID_RESPONSE }], null, null);
267
+ const [{ url, type }] = allSyncs;
268
+ const { bidders, endpoint } = parseUrl(url).search;
269
+ it('should return a single sync object', () => {
270
+ expect(allSyncs.length).equal(1);
271
+ });
272
+ it('should use iframe sync when available', () => {
273
+ expect(type).equal('iframe');
274
+ });
275
+ it('should sync to all s2s bidders', () => {
276
+ expect(bidders.split(',').sort()).to.deep.equal(['appnexus', 'pubmatic']);
277
+ });
278
+ it('should sync to the right endpoint', () => {
279
+ expect(endpoint).equal(`https://${PBS_HOST}/cookie_sync`);
280
+ });
281
+ it('should not sync to the same s2s bidders when called again', () => {
282
+ const newSyncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: BID_RESPONSE }], null, null);
283
+ expect(newSyncs).to.deep.equal([]);
284
+ });
285
+ });
286
+ describe('getUserSyncs with pixelEnabled', () => {
287
+ resetAndBuildRequest()
288
+ const responseSyncs = BID_RESPONSE.ext.relevant.sync;
289
+ const allSyncs = spec.getUserSyncs({ pixelEnabled: true }, [{ body: BID_RESPONSE }], null, null);
290
+ it('should return one sync object per pixel', () => {
291
+ const expectedResult = responseSyncs.map(({ url }) => ({url, type: 'image'}));
292
+ expect(allSyncs).to.deep.equal(expectedResult)
293
+ });
294
+ });
295
+ });
@@ -282,6 +282,28 @@ describe('RTBHouseAdapter', () => {
282
282
  expect(data.source).to.not.have.property('ext');
283
283
  });
284
284
 
285
+ it('should include first party data', function () {
286
+ const bidRequest = Object.assign([], bidRequests);
287
+ const localBidderRequest = {
288
+ ...bidderRequest,
289
+ ortb2: {
290
+ bcat: ['IAB1', 'IAB2-1'],
291
+ badv: ['domain1.com', 'domain2.com'],
292
+ site: { ext: { data: 'some site data' } },
293
+ device: { ext: { data: 'some device data' } },
294
+ user: { ext: { data: 'some user data' } }
295
+ }
296
+ };
297
+
298
+ const request = spec.buildRequests(bidRequest, localBidderRequest);
299
+ const data = JSON.parse(request.data);
300
+ expect(data.bcat).to.deep.equal(localBidderRequest.ortb2.bcat);
301
+ expect(data.badv).to.deep.equal(localBidderRequest.ortb2.badv);
302
+ expect(data.site).to.nested.include({'ext.data': 'some site data'});
303
+ expect(data.device).to.nested.include({'ext.data': 'some device data'});
304
+ expect(data.user).to.nested.include({'ext.data': 'some user data'});
305
+ });
306
+
285
307
  context('FLEDGE', function() {
286
308
  afterEach(function () {
287
309
  config.resetConfig();
@@ -631,10 +653,10 @@ describe('RTBHouseAdapter', () => {
631
653
  expect(bids[0].meta.advertiserDomains).to.deep.equal(['rtbhouse.com']);
632
654
  expect(bids[0].native).to.deep.equal({
633
655
  title: 'Title text',
634
- clickUrl: encodeURIComponent('https://example.com'),
656
+ clickUrl: encodeURI('https://example.com'),
635
657
  impressionTrackers: ['https://example.com/imptracker'],
636
658
  image: {
637
- url: encodeURIComponent('https://example.com/image.jpg'),
659
+ url: encodeURI('https://example.com/image.jpg'),
638
660
  width: 150,
639
661
  height: 50
640
662
  },
@@ -248,6 +248,71 @@ describe('sovrnBidAdapter', function() {
248
248
  expect(data.regs.ext['us_privacy']).to.equal(bidderRequest.uspConsent)
249
249
  })
250
250
 
251
+ it('should send gpp info in OpenRTB 2.6 location when gppConsent defined', function () {
252
+ const bidderRequest = {
253
+ ...baseBidderRequest,
254
+ bidderCode: 'sovrn',
255
+ auctionId: '1d1a030790a475',
256
+ bidderRequestId: '22edbae2733bf6',
257
+ timeout: 3000,
258
+ gppConsent: {
259
+ gppString: 'gppstring',
260
+ applicableSections: [8]
261
+ },
262
+ bids: [baseBidRequest]
263
+ }
264
+ const { regs } = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data)
265
+ expect(regs.gpp).to.equal('gppstring')
266
+ expect(regs.gpp_sid).to.be.an('array')
267
+ expect(regs.gpp_sid).to.include(8)
268
+ })
269
+
270
+ it('should not send gpp info when gppConsent is not defined', function () {
271
+ const bidderRequest = {
272
+ ...baseBidderRequest,
273
+ bidderCode: 'sovrn',
274
+ auctionId: '1d1a030790a475',
275
+ bidderRequestId: '22edbae2733bf6',
276
+ timeout: 3000,
277
+ bids: [baseBidRequest],
278
+ gdprConsent: {
279
+ consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==',
280
+ gdprApplies: true
281
+ },
282
+ }
283
+ const { regs } = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data)
284
+ expect(regs.gpp).to.be.undefined
285
+ })
286
+
287
+ it('should send gdpr info even when gppConsent defined', function () {
288
+ const bidderRequest = {
289
+ ...baseBidderRequest,
290
+ bidderCode: 'sovrn',
291
+ auctionId: '1d1a030790a475',
292
+ bidderRequestId: '22edbae2733bf6',
293
+ timeout: 3000,
294
+ gdprConsent: {
295
+ consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==',
296
+ gdprApplies: true
297
+ },
298
+ gppConsent: {
299
+ gppString: 'gppstring',
300
+ applicableSections: [8]
301
+ },
302
+ bids: [baseBidRequest]
303
+ }
304
+
305
+ const { regs, user } = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data)
306
+
307
+ expect(regs.ext.gdpr).to.exist.and.to.be.a('number')
308
+ expect(regs.ext.gdpr).to.equal(1)
309
+ expect(user.ext.consent).to.exist.and.to.be.a('string')
310
+ expect(user.ext.consent).to.equal(bidderRequest.gdprConsent.consentString)
311
+ expect(regs.gpp).to.equal('gppstring')
312
+ expect(regs.gpp_sid).to.be.an('array')
313
+ expect(regs.gpp_sid).to.include(8)
314
+ })
315
+
251
316
  it('should add schain if present', function() {
252
317
  const schainRequest = {
253
318
  ...baseBidRequest,