prebid.js 7.51.0 → 7.53.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 (277) hide show
  1. package/dist/1plusXRtdProvider.js +1 -1
  2. package/dist/33acrossBidAdapter.js +1 -1
  3. package/dist/33acrossIdSystem.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/adkernelBidAdapter.js +1 -1
  8. package/dist/adqueryBidAdapter.js +1 -1
  9. package/dist/adrelevantisBidAdapter.js +1 -1
  10. package/dist/adriverIdSystem.js +1 -1
  11. package/dist/adtrgtmeBidAdapter.js +1 -1
  12. package/dist/adxcgBidAdapter.js +1 -1
  13. package/dist/adyoulikeBidAdapter.js +1 -1
  14. package/dist/airgridRtdProvider.js +1 -1
  15. package/dist/ajaBidAdapter.js +1 -1
  16. package/dist/allowActivities.js +1 -0
  17. package/dist/amxBidAdapter.js +1 -1
  18. package/dist/amxIdSystem.js +1 -1
  19. package/dist/appierAnalyticsAdapter.js +1 -1
  20. package/dist/appnexusBidAdapter.js +1 -1
  21. package/dist/asoBidAdapter.js +1 -1
  22. package/dist/axonixBidAdapter.js +1 -1
  23. package/dist/beopBidAdapter.js +1 -1
  24. package/dist/bidglassBidAdapter.js +1 -1
  25. package/dist/big-richmediaBidAdapter.js +1 -1
  26. package/dist/bridgewellBidAdapter.js +1 -1
  27. package/dist/brightMountainMediaBidAdapter.js +1 -1
  28. package/dist/carodaBidAdapter.js +1 -1
  29. package/dist/chtnwBidAdapter.js +1 -1
  30. package/dist/conceptxBidAdapter.js +1 -0
  31. package/dist/concertBidAdapter.js +1 -1
  32. package/dist/connectIdSystem.js +1 -1
  33. package/dist/connectadBidAdapter.js +1 -1
  34. package/dist/consumableBidAdapter.js +1 -1
  35. package/dist/conversantAnalyticsAdapter.js +1 -1
  36. package/dist/conversantBidAdapter.js +1 -1
  37. package/dist/craftBidAdapter.js +1 -1
  38. package/dist/criteoBidAdapter.js +1 -1
  39. package/dist/cwireBidAdapter.js +1 -1
  40. package/dist/dependencies.json +6 -0
  41. package/dist/dspxBidAdapter.js +1 -1
  42. package/dist/eplanningBidAdapter.js +1 -1
  43. package/dist/eskimiBidAdapter.js +1 -1
  44. package/dist/euidIdSystem.js +1 -0
  45. package/dist/feedadBidAdapter.js +1 -1
  46. package/dist/finativeBidAdapter.js +1 -1
  47. package/dist/freepassIdSystem.js +1 -0
  48. package/dist/freewheel-sspBidAdapter.js +1 -1
  49. package/dist/gdprEnforcement.js +1 -1
  50. package/dist/glimpseBidAdapter.js +1 -1
  51. package/dist/gmosspBidAdapter.js +1 -1
  52. package/dist/goldbachBidAdapter.js +1 -1
  53. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  54. package/dist/greenbidsRtdProvider.js +1 -1
  55. package/dist/gridBidAdapter.js +1 -1
  56. package/dist/growthCodeRtdProvider.js +1 -0
  57. package/dist/gumgumBidAdapter.js +1 -1
  58. package/dist/h12mediaBidAdapter.js +1 -1
  59. package/dist/id5IdSystem.js +1 -1
  60. package/dist/improvedigitalBidAdapter.js +1 -1
  61. package/dist/inmarBidAdapter.js +1 -1
  62. package/dist/insticatorBidAdapter.js +1 -1
  63. package/dist/ixBidAdapter.js +1 -1
  64. package/dist/justpremiumBidAdapter.js +1 -1
  65. package/dist/kargoBidAdapter.js +1 -1
  66. package/dist/konduitAnalyticsAdapter.js +1 -1
  67. package/dist/kueezBidAdapter.js +1 -1
  68. package/dist/kueezRtbBidAdapter.js +1 -1
  69. package/dist/kulturemediaBidAdapter.js +1 -1
  70. package/dist/lassoBidAdapter.js +1 -1
  71. package/dist/lifestreetBidAdapter.js +1 -1
  72. package/dist/limelightDigitalBidAdapter.js +1 -1
  73. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  74. package/dist/logicadBidAdapter.js +1 -1
  75. package/dist/loglyliftBidAdapter.js +1 -1
  76. package/dist/magniteAnalyticsAdapter.js +1 -1
  77. package/dist/malltvAnalyticsAdapter.js +1 -1
  78. package/dist/marsmediaBidAdapter.js +1 -1
  79. package/dist/mediafuseBidAdapter.js +1 -1
  80. package/dist/mediasquareBidAdapter.js +1 -1
  81. package/dist/mgidBidAdapter.js +1 -1
  82. package/dist/minutemediaBidAdapter.js +1 -1
  83. package/dist/minutemediaplusBidAdapter.js +1 -1
  84. package/dist/nexx360BidAdapter.js +1 -1
  85. package/dist/not-for-prod/prebid.js +154 -146
  86. package/dist/objectGuard.js +1 -0
  87. package/dist/oguryBidAdapter.js +1 -1
  88. package/dist/onetagBidAdapter.js +1 -1
  89. package/dist/ooloAnalyticsAdapter.js +1 -1
  90. package/dist/optidigitalBidAdapter.js +1 -1
  91. package/dist/outbrainBidAdapter.js +1 -1
  92. package/dist/oxxionAnalyticsAdapter.js +1 -0
  93. package/dist/pairIdSystem.js +1 -1
  94. package/dist/parrableIdSystem.js +1 -1
  95. package/dist/pixfutureBidAdapter.js +1 -1
  96. package/dist/prebid-core.js +1 -1
  97. package/dist/proxistoreBidAdapter.js +1 -1
  98. package/dist/publinkIdSystem.js +1 -1
  99. package/dist/pubmaticBidAdapter.js +1 -1
  100. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  101. package/dist/pxyzBidAdapter.js +1 -1
  102. package/dist/quantcastBidAdapter.js +1 -1
  103. package/dist/readpeakBidAdapter.js +1 -1
  104. package/dist/relaidoBidAdapter.js +1 -1
  105. package/dist/retailspotBidAdapter.js +1 -1
  106. package/dist/rhythmoneBidAdapter.js +1 -1
  107. package/dist/richaudienceBidAdapter.js +1 -1
  108. package/dist/riseBidAdapter.js +1 -1
  109. package/dist/rtdModule.js +1 -1
  110. package/dist/rubiconAnalyticsAdapter.js +1 -1
  111. package/dist/rubiconBidAdapter.js +1 -1
  112. package/dist/schain.js +1 -1
  113. package/dist/seedingAllianceBidAdapter.js +1 -1
  114. package/dist/seedtagBidAdapter.js +1 -1
  115. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  116. package/dist/sharethroughBidAdapter.js +1 -1
  117. package/dist/shinezBidAdapter.js +1 -1
  118. package/dist/sirdataRtdProvider.js +1 -1
  119. package/dist/smaatoBidAdapter.js +1 -1
  120. package/dist/smartadserverBidAdapter.js +1 -1
  121. package/dist/smartxBidAdapter.js +1 -1
  122. package/dist/smilewantedBidAdapter.js +1 -1
  123. package/dist/sonobiBidAdapter.js +1 -1
  124. package/dist/sovrnAnalyticsAdapter.js +1 -1
  125. package/dist/sovrnBidAdapter.js +1 -1
  126. package/dist/sspBCBidAdapter.js +1 -1
  127. package/dist/stroeerCoreBidAdapter.js +1 -1
  128. package/dist/stvBidAdapter.js +1 -1
  129. package/dist/sublimeBidAdapter.js +1 -1
  130. package/dist/synacormediaBidAdapter.js +1 -1
  131. package/dist/targetVideoBidAdapter.js +1 -1
  132. package/dist/teadsBidAdapter.js +1 -1
  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/uid2IdSystem.js +1 -1
  138. package/dist/uid2IdSystem_shared.js +1 -0
  139. package/dist/underdogmediaBidAdapter.js +1 -1
  140. package/dist/undertoneBidAdapter.js +1 -1
  141. package/dist/userId.js +1 -1
  142. package/dist/vidazooBidAdapter.js +1 -1
  143. package/dist/videobyteBidAdapter.js +1 -1
  144. package/dist/viouslyBidAdapter.js +1 -1
  145. package/dist/visxBidAdapter.js +1 -1
  146. package/dist/vuukleBidAdapter.js +1 -1
  147. package/dist/weboramaRtdProvider.js +1 -1
  148. package/dist/widespaceBidAdapter.js +1 -1
  149. package/dist/winrBidAdapter.js +1 -1
  150. package/dist/yahoosspBidAdapter.js +1 -1
  151. package/dist/yieldlabBidAdapter.js +1 -1
  152. package/dist/yieldmoBidAdapter.js +1 -1
  153. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  154. package/dist/zeta_global_sspBidAdapter.js +1 -1
  155. package/integrationExamples/gpt/growthcode.html +20 -9
  156. package/integrationExamples/gpt/userId_example.html +20 -6
  157. package/libraries/objectGuard/objectGuard.js +108 -0
  158. package/libraries/objectGuard/ortbGuard.js +88 -0
  159. package/modules/.submodules.json +3 -1
  160. package/modules/1plusXRtdProvider.js +31 -60
  161. package/modules/adagioBidAdapter.js +86 -24
  162. package/modules/adgenerationBidAdapter.js +14 -5
  163. package/modules/adkernelBidAdapter.js +2 -2
  164. package/modules/adriverIdSystem.js +1 -1
  165. package/modules/airgridRtdProvider.js +11 -12
  166. package/modules/allowActivities.js +74 -0
  167. package/modules/asoBidAdapter.js +2 -1
  168. package/modules/beopBidAdapter.js +6 -0
  169. package/modules/conceptxBidAdapter.js +70 -0
  170. package/modules/conceptxBidAdapter.md +36 -0
  171. package/modules/connectIdSystem.js +89 -13
  172. package/modules/connectIdSystem.md +4 -7
  173. package/modules/criteoBidAdapter.js +18 -2
  174. package/modules/eskimiBidAdapter.js +171 -41
  175. package/modules/eskimiBidAdapter.md +35 -16
  176. package/modules/euidIdSystem.js +121 -0
  177. package/modules/euidIdSystem.md +131 -0
  178. package/modules/freepassIdSystem.js +61 -0
  179. package/modules/freepassIdSystem.md +47 -0
  180. package/modules/gdprEnforcement.js +98 -169
  181. package/modules/greenbidsAnalyticsAdapter.js +1 -1
  182. package/modules/growthCodeRtdProvider.js +131 -0
  183. package/modules/growthCodeRtdProvider.md +55 -0
  184. package/modules/id5IdSystem.js +3 -5
  185. package/modules/ixBidAdapter.js +17 -3
  186. package/modules/limelightDigitalBidAdapter.js +1 -1
  187. package/modules/logicadBidAdapter.js +14 -1
  188. package/modules/mediasquareBidAdapter.js +13 -5
  189. package/modules/nexx360BidAdapter.js +1 -0
  190. package/modules/oxxionAnalyticsAdapter.js +212 -0
  191. package/modules/oxxionAnalyticsAdapter.md +33 -0
  192. package/modules/pairIdSystem.js +16 -11
  193. package/modules/proxistoreBidAdapter.js +11 -14
  194. package/modules/richaudienceBidAdapter.js +10 -1
  195. package/modules/riseBidAdapter.js +1 -1
  196. package/modules/rtdModule/index.js +12 -1
  197. package/modules/schain.js +2 -2
  198. package/modules/sharethroughBidAdapter.js +2 -2
  199. package/modules/sirdataRtdProvider.js +73 -146
  200. package/modules/smartadserverBidAdapter.js +5 -0
  201. package/modules/sovrnBidAdapter.js +4 -1
  202. package/modules/stroeerCoreBidAdapter.js +55 -6
  203. package/modules/stvBidAdapter.js +34 -1
  204. package/modules/uid2IdSystem.js +27 -210
  205. package/modules/uid2IdSystem.md +104 -23
  206. package/modules/uid2IdSystem_shared.js +232 -0
  207. package/modules/undertoneBidAdapter.js +9 -1
  208. package/modules/userId/eids.js +8 -0
  209. package/modules/userId/index.js +69 -41
  210. package/modules/userId/userId.md +2 -1
  211. package/modules/viouslyBidAdapter.js +2 -2
  212. package/modules/weboramaRtdProvider.js +25 -95
  213. package/modules/weboramaRtdProvider.md +4 -4
  214. package/modules/yahoosspBidAdapter.js +45 -3
  215. package/modules/yahoosspBidAdapter.md +1 -1
  216. package/modules/yieldlabBidAdapter.js +23 -14
  217. package/modules/zeta_global_sspBidAdapter.js +28 -22
  218. package/package.json +1 -1
  219. package/src/activities/activities.js +47 -0
  220. package/src/activities/activityParams.js +8 -0
  221. package/src/activities/modules.js +1 -1
  222. package/src/activities/params.js +59 -0
  223. package/src/activities/redactor.js +157 -0
  224. package/src/activities/rules.js +95 -0
  225. package/src/adapterManager.js +45 -8
  226. package/src/adloader.js +1 -0
  227. package/src/fpd/rootDomain.js +1 -1
  228. package/src/prebid.js +1 -1
  229. package/src/storageManager.js +57 -44
  230. package/src/userSync.js +35 -18
  231. package/test/spec/activities/allowActivites_spec.js +138 -0
  232. package/test/spec/activities/objectGuard_spec.js +144 -0
  233. package/test/spec/activities/ortbGuard_spec.js +140 -0
  234. package/test/spec/activities/params_spec.js +25 -0
  235. package/test/spec/activities/redactor_spec.js +296 -0
  236. package/test/spec/activities/rules_spec.js +135 -0
  237. package/test/spec/modules/1plusXRtdProvider_spec.js +98 -149
  238. package/test/spec/modules/adagioBidAdapter_spec.js +46 -17
  239. package/test/spec/modules/adgenerationBidAdapter_spec.js +52 -12
  240. package/test/spec/modules/airgridRtdProvider_spec.js +2 -0
  241. package/test/spec/modules/beopBidAdapter_spec.js +24 -0
  242. package/test/spec/modules/conceptxBidAdapter_spec.js +136 -0
  243. package/test/spec/modules/connectIdSystem_spec.js +291 -23
  244. package/test/spec/modules/criteoBidAdapter_spec.js +85 -1
  245. package/test/spec/modules/eids_spec.js +15 -0
  246. package/test/spec/modules/eskimiBidAdapter_spec.js +264 -112
  247. package/test/spec/modules/euidIdSystem_spec.js +130 -0
  248. package/test/spec/modules/freepassIdSystem_spec.js +186 -0
  249. package/test/spec/modules/gdprEnforcement_spec.js +127 -414
  250. package/test/spec/modules/growthCodeRtdProvider_spec.js +127 -0
  251. package/test/spec/modules/id5IdSystem_spec.js +10 -3
  252. package/test/spec/modules/ixBidAdapter_spec.js +32 -1
  253. package/test/spec/modules/logicadBidAdapter_spec.js +122 -2
  254. package/test/spec/modules/mediasquareBidAdapter_spec.js +4 -0
  255. package/test/spec/modules/oxxionAnalyticsAdapter_spec.js +324 -0
  256. package/test/spec/modules/pairIdSystem_spec.js +16 -3
  257. package/test/spec/modules/realTimeDataModule_spec.js +1 -1
  258. package/test/spec/modules/richaudienceBidAdapter_spec.js +44 -0
  259. package/test/spec/modules/schain_spec.js +9 -0
  260. package/test/spec/modules/sharethroughBidAdapter_spec.js +1 -1
  261. package/test/spec/modules/sirdataRtdProvider_spec.js +110 -17
  262. package/test/spec/modules/smartadserverBidAdapter_spec.js +42 -0
  263. package/test/spec/modules/sovrnBidAdapter_spec.js +13 -0
  264. package/test/spec/modules/stroeerCoreBidAdapter_spec.js +151 -6
  265. package/test/spec/modules/stvBidAdapter_spec.js +13 -1
  266. package/test/spec/modules/uid2IdSystem_helpers.js +70 -0
  267. package/test/spec/modules/uid2IdSystem_spec.js +131 -86
  268. package/test/spec/modules/undertoneBidAdapter_spec.js +57 -1
  269. package/test/spec/modules/userId_spec.js +96 -33
  270. package/test/spec/modules/weboramaRtdProvider_spec.js +331 -205
  271. package/test/spec/modules/yahoosspBidAdapter_spec.js +103 -51
  272. package/test/spec/modules/yieldlabBidAdapter_spec.js +42 -2
  273. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +204 -4
  274. package/test/spec/unit/core/adapterManager_spec.js +181 -1
  275. package/test/spec/unit/core/storageManager_spec.js +76 -68
  276. package/test/spec/unit/pbjs_api_spec.js +15 -25
  277. package/test/spec/userSync_spec.js +45 -16
@@ -1,11 +1,15 @@
1
+ /* eslint-disable no-console */
2
+
1
3
  import {coreStorage, init, setSubmoduleRegistry, requestBidsHook} from 'modules/userId/index.js';
2
4
  import {config} from 'src/config.js';
3
5
  import * as utils from 'src/utils.js';
4
6
  import { uid2IdSubmodule } from 'modules/uid2IdSystem.js';
5
7
  import 'src/prebid.js';
8
+ import 'modules/consentManagement.js';
6
9
  import { getGlobal } from 'src/prebidGlobal.js';
7
10
  import { server } from 'test/mocks/xhr.js';
8
11
  import { configureTimerInterceptors } from 'test/mocks/timers.js';
12
+ import { cookieHelpers, runAuction, apiHelpers, setGdprApplies } from './uid2IdSystem_helpers.js';
9
13
  import {hook} from 'src/hook.js';
10
14
  import {uninstall as uninstallGdprEnforcement} from 'modules/gdprEnforcement.js';
11
15
 
@@ -14,72 +18,48 @@ let expect = require('chai').expect;
14
18
  const clearTimersAfterEachTest = true;
15
19
  const debugOutput = () => {};
16
20
 
17
- const expireCookieDate = 'Thu, 01 Jan 1970 00:00:01 GMT';
18
- const msIn12Hours = 60 * 60 * 12 * 1000;
19
21
  const moduleCookieName = '__uid2_advertising_token';
20
22
  const publisherCookieName = '__UID2_SERVER_COOKIE';
21
23
  const auctionDelayMs = 10;
22
- const legacyConfigParams = null;
23
- const serverCookieConfigParams = { uid2ServerCookie: publisherCookieName }
24
- const getFutureCookieExpiry = () => new Date(Date.now() + msIn12Hours).toUTCString();
25
- const setPublisherCookie = (token) => coreStorage.setCookie(publisherCookieName, JSON.stringify(token), getFutureCookieExpiry());
26
-
27
- const makePrebidIdentityContainer = (token) => ({uid2: {id: token}});
28
- const makePrebidConfig = (params = null, extraSettings = {}, debug = false) => ({
29
- userSync: { auctionDelay: auctionDelayMs, userIds: [{name: 'uid2', params}] }, debug, ...extraSettings
30
- });
31
-
32
24
  const initialToken = `initial-advertising-token`;
33
25
  const legacyToken = 'legacy-advertising-token';
34
26
  const refreshedToken = 'refreshed-advertising-token';
35
- const makeUid2Token = (token = initialToken, shouldRefresh = false, expired = false) => ({
36
- advertising_token: token,
37
- refresh_token: 'fake-refresh-token',
38
- identity_expires: expired ? Date.now() - 1000 : Date.now() + 60 * 60 * 1000,
39
- refresh_from: shouldRefresh ? Date.now() - 1000 : Date.now() + 60 * 1000,
40
- refresh_expires: Date.now() + 24 * 60 * 60 * 1000, // 24 hours
41
- refresh_response_key: 'wR5t6HKMfJ2r4J7fEGX9Gw==',
27
+
28
+ const legacyConfigParams = {storage: null};
29
+ const serverCookieConfigParams = { uid2ServerCookie: publisherCookieName };
30
+ const newServerCookieConfigParams = { uid2Cookie: publisherCookieName };
31
+
32
+ const makeUid2IdentityContainer = (token) => ({uid2: {id: token}});
33
+ let useLocalStorage = false;
34
+ const makePrebidConfig = (params = null, extraSettings = {}, debug = false) => ({
35
+ userSync: { auctionDelay: auctionDelayMs, userIds: [{name: 'uid2', params: {storage: useLocalStorage ? 'localStorage' : 'cookie', ...params}}] }, debug, ...extraSettings
42
36
  });
43
- const expectInitialToken = (bid) => expect(bid?.userId ?? {}).to.deep.include(makePrebidIdentityContainer(initialToken));
44
- const expectRefreshedToken = (bid) => expect(bid?.userId ?? {}).to.deep.include(makePrebidIdentityContainer(refreshedToken));
37
+
38
+ const getFromAppropriateStorage = () => {
39
+ if (useLocalStorage) return coreStorage.getDataFromLocalStorage(moduleCookieName);
40
+ else return coreStorage.getCookie(moduleCookieName);
41
+ }
42
+
43
+ const expectToken = (bid, token) => expect(bid?.userId ?? {}).to.deep.include(makeUid2IdentityContainer(token));
44
+ const expectLegacyToken = (bid) => expect(bid.userId).to.deep.include(makeUid2IdentityContainer(legacyToken));
45
45
  const expectNoIdentity = (bid) => expect(bid).to.not.haveOwnProperty('userId');
46
- const expectGlobalToHaveRefreshedIdentity = () => expect(getGlobal().getUserIds()).to.deep.include(makePrebidIdentityContainer(refreshedToken));
46
+ const expectGlobalToHaveToken = (token) => expect(getGlobal().getUserIds()).to.deep.include(makeUid2IdentityContainer(token));
47
47
  const expectGlobalToHaveNoUid2 = () => expect(getGlobal().getUserIds()).to.not.haveOwnProperty('uid2');
48
- const expectLegacyToken = (bid) => expect(bid.userId).to.deep.include(makePrebidIdentityContainer(legacyToken));
49
- const expectNoLegacyToken = (bid) => expect(bid.userId).to.not.deep.include(makePrebidIdentityContainer(legacyToken));
50
- const expectModuleCookieEmptyOrMissing = () => expect(coreStorage.getCookie(moduleCookieName)).to.be.null;
51
- const expectModuleCookieToContain = (initialIdentity, latestIdentity) => {
52
- const cookie = JSON.parse(coreStorage.getCookie(moduleCookieName));
48
+ const expectNoLegacyToken = (bid) => expect(bid.userId).to.not.deep.include(makeUid2IdentityContainer(legacyToken));
49
+ const expectModuleStorageEmptyOrMissing = () => expect(getFromAppropriateStorage()).to.be.null;
50
+ const expectModuleStorageToContain = (initialIdentity, latestIdentity) => {
51
+ const cookie = JSON.parse(getFromAppropriateStorage());
53
52
  if (initialIdentity) expect(cookie.originalToken.advertising_token).to.equal(initialIdentity);
54
53
  if (latestIdentity) expect(cookie.latestToken.advertising_token).to.equal(latestIdentity);
55
54
  }
56
55
 
57
56
  const apiUrl = 'https://prod.uidapi.com/v2/token/refresh';
58
57
  const headers = { 'Content-Type': 'application/json' };
59
- const makeSuccessResponseBody = () => btoa(JSON.stringify({ status: 'success', body: { ...makeUid2Token(), advertising_token: refreshedToken } }));
58
+ const makeSuccessResponseBody = () => btoa(JSON.stringify({ status: 'success', body: { ...apiHelpers.makeTokenResponse(initialToken), advertising_token: refreshedToken } }));
60
59
  const configureUid2Response = (httpStatus, response) => server.respondWith('POST', apiUrl, (xhr) => xhr.respond(httpStatus, headers, response));
61
60
  const configureUid2ApiSuccessResponse = () => configureUid2Response(200, makeSuccessResponseBody());
62
61
  const configureUid2ApiFailResponse = () => configureUid2Response(500, 'Error');
63
62
 
64
- const respondAfterDelay = (delay) => new Promise((resolve) => setTimeout(() => {
65
- server.respond();
66
- setTimeout(() => resolve());
67
- }, delay));
68
-
69
- const runAuction = async () => {
70
- const adUnits = [{
71
- code: 'adUnit-code',
72
- mediaTypes: {banner: {}, native: {}},
73
- sizes: [[300, 200], [300, 600]],
74
- bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}]
75
- }];
76
- return new Promise(function(resolve) {
77
- requestBidsHook(function() {
78
- resolve(adUnits[0].bids[0]);
79
- }, {adUnits});
80
- });
81
- }
82
-
83
63
  // Runs the provided test twice - once with a successful API mock, once with one which returns a server error
84
64
  const testApiSuccessAndFailure = (act, testDescription, failTestDescription, only = false) => {
85
65
  const testFn = only ? it.only : it;
@@ -92,6 +72,26 @@ const testApiSuccessAndFailure = (act, testDescription, failTestDescription, onl
92
72
  await act(false);
93
73
  });
94
74
  }
75
+
76
+ const testCookieAndLocalStorage = (description, test, only = false) => {
77
+ const describeFn = only ? describe.only : describe;
78
+ describeFn(`Using cookies: ${description}`, async function() {
79
+ before(function() {
80
+ useLocalStorage = false;
81
+ });
82
+ await test();
83
+ });
84
+ describeFn(`Using local storage: ${description}`, async function() {
85
+ before(function() {
86
+ useLocalStorage = true;
87
+ });
88
+ after(function() {
89
+ useLocalStorage = false;
90
+ });
91
+ await test();
92
+ });
93
+ };
94
+
95
95
  describe(`UID2 module`, function () {
96
96
  let suiteSandbox, testSandbox, timerSpy, fullTestTitle, restoreSubtleToUndefined = false;
97
97
  before(function () {
@@ -141,21 +141,21 @@ describe(`UID2 module`, function () {
141
141
  await timerSpy.waitAllActiveTimers();
142
142
  }
143
143
  }
144
- coreStorage.setCookie(moduleCookieName, '', expireCookieDate);
145
- coreStorage.setCookie(publisherCookieName, '', expireCookieDate);
144
+ cookieHelpers.clearCookies(moduleCookieName, publisherCookieName);
145
+ coreStorage.removeDataFromLocalStorage(moduleCookieName);
146
146
 
147
147
  debugOutput('----------------- END TEST ------------------');
148
148
  });
149
149
 
150
150
  describe('Configuration', function() {
151
151
  it('When no baseUrl is provided in config, the module calls the production endpoint', function() {
152
- const uid2Token = makeUid2Token(initialToken, true, true);
152
+ const uid2Token = apiHelpers.makeTokenResponse(initialToken, true, true);
153
153
  config.setConfig(makePrebidConfig({uid2Token}));
154
154
  expect(server.requests[0]?.url).to.have.string('https://prod.uidapi.com/');
155
155
  });
156
156
 
157
157
  it('When a baseUrl is provided in config, the module calls the provided endpoint', function() {
158
- const uid2Token = makeUid2Token(initialToken, true, true);
158
+ const uid2Token = apiHelpers.makeTokenResponse(initialToken, true, true);
159
159
  config.setConfig(makePrebidConfig({uid2Token, uid2ApiBase: 'https://operator-integ.uidapi.com'}));
160
160
  expect(server.requests[0]?.url).to.have.string('https://operator-integ.uidapi.com/');
161
161
  });
@@ -170,14 +170,25 @@ describe(`UID2 module`, function () {
170
170
  expectLegacyToken(bid);
171
171
  });
172
172
 
173
+ it('When a legacy value is provided directly in configuration but GDPR applies, it is not passed on', async function() {
174
+ const valueConfig = makePrebidConfig();
175
+ setGdprApplies();
176
+ valueConfig.userSync.userIds[0].value = {uid2: {id: legacyToken}}
177
+ config.setConfig(valueConfig);
178
+ const bid = await runAuction();
179
+
180
+ expectNoIdentity(bid);
181
+ });
182
+
173
183
  // These tests cover 'legacy' cookies - i.e. cookies set with just the uid2 advertising token, which was how some previous integrations worked.
174
184
  // Some users might still have this cookie, and the module should use that token if a newer one isn't provided.
175
185
  // This should cover older integrations where the server is setting this legacy cookie and expecting the module to pass it on.
176
186
  describe('When a legacy cookie exists', function () {
177
187
  // Creates a test which sets the legacy cookie, configures the UID2 module with provided params, runs an
178
- const createLegacyTest = function(params, bidAssertions) {
188
+ const createLegacyTest = function(params, bidAssertions, addConsent = false) {
179
189
  return async function() {
180
- coreStorage.setCookie(moduleCookieName, legacyToken, getFutureCookieExpiry());
190
+ coreStorage.setCookie(moduleCookieName, legacyToken, cookieHelpers.getFutureCookieExpiry());
191
+ if (addConsent) setGdprApplies();
181
192
  config.setConfig(makePrebidConfig(params));
182
193
 
183
194
  const bid = await runAuction();
@@ -189,120 +200,154 @@ describe(`UID2 module`, function () {
189
200
  createLegacyTest(legacyConfigParams, [expectLegacyToken]));
190
201
  it('and a server cookie config is used without a valid server cookie, it should provide the legacy cookie',
191
202
  createLegacyTest(serverCookieConfigParams, [expectLegacyToken]));
203
+ it('and a server cookie is used with a valid server cookie configured using the new param name, it should provide the server cookie',
204
+ async function() { cookieHelpers.setPublisherCookie(publisherCookieName, apiHelpers.makeTokenResponse(initialToken)); await createLegacyTest(serverCookieConfigParams, [(bid) => expectToken(bid, initialToken), expectNoLegacyToken])(); });
192
205
  it('and a server cookie is used with a valid server cookie, it should provide the server cookie',
193
- async function() { setPublisherCookie(makeUid2Token()); await createLegacyTest(serverCookieConfigParams, [expectInitialToken, expectNoLegacyToken])(); });
206
+ async function() { cookieHelpers.setPublisherCookie(publisherCookieName, apiHelpers.makeTokenResponse(initialToken)); await createLegacyTest(newServerCookieConfigParams, [(bid) => expectToken(bid, initialToken), expectNoLegacyToken])(); });
194
207
  it('and a token is provided in config, it should provide the config token',
195
- createLegacyTest({uid2Token: makeUid2Token()}, [expectInitialToken, expectNoLegacyToken]));
208
+ createLegacyTest({uid2Token: apiHelpers.makeTokenResponse(initialToken)}, [(bid) => expectToken(bid, initialToken), expectNoLegacyToken]));
209
+ it('and GDPR applies, no identity should be provided to the auction',
210
+ createLegacyTest(legacyConfigParams, [expectNoIdentity], true));
211
+ it('and GDPR applies, when getId is called directly it provides no identity', () => {
212
+ coreStorage.setCookie(moduleCookieName, legacyToken, cookieHelpers.getFutureCookieExpiry());
213
+ const consentConfig = setGdprApplies();
214
+ let configObj = makePrebidConfig(legacyConfigParams);
215
+ const result = uid2IdSubmodule.getId(configObj.userSync.userIds[0], consentConfig.consentData);
216
+ expect(result?.id).to.not.exist;
217
+ });
218
+
219
+ it('multiple runs do not change the value', async function() {
220
+ coreStorage.setCookie(moduleCookieName, legacyToken, cookieHelpers.getFutureCookieExpiry());
221
+ config.setConfig(makePrebidConfig(legacyConfigParams));
222
+
223
+ const bid = await runAuction();
224
+
225
+ console.log('Storage', coreStorage.getDataFromLocalStorage(moduleCookieName));
226
+ init(config);
227
+ setSubmoduleRegistry([uid2IdSubmodule]);
228
+ config.setConfig(makePrebidConfig(legacyConfigParams));
229
+ const bid2 = await runAuction();
230
+
231
+ expect(bid.userId.uid2.id).to.equal(bid2.userId.uid2.id);
232
+ });
196
233
  });
197
234
 
198
235
  // This setup runs all of the functional tests with both types of config - the full token response in params, or a server cookie with the cookie name provided
199
236
  let scenarios = [
200
237
  {
201
238
  name: 'Token provided in config call',
202
- setConfig: (token, extraConfig = {}) => config.setConfig(makePrebidConfig({uid2Token: token}, extraConfig)),
239
+ setConfig: (token, extraConfig = {}) => {
240
+ const gen = makePrebidConfig({uid2Token: token}, extraConfig);
241
+ console.log('GENERATED CONFIG', gen.userSync.userIds[0].params);
242
+ return config.setConfig(gen);
243
+ },
203
244
  },
204
245
  {
205
246
  name: 'Token provided in server-set cookie',
206
247
  setConfig: (token, extraConfig) => {
207
- setPublisherCookie(token);
248
+ cookieHelpers.setPublisherCookie(publisherCookieName, token);
208
249
  config.setConfig(makePrebidConfig(serverCookieConfigParams, extraConfig));
209
250
  },
210
251
  }
211
252
  ]
212
253
 
213
254
  scenarios.forEach(function(scenario) {
214
- describe(scenario.name, function() {
255
+ testCookieAndLocalStorage(scenario.name, function() {
215
256
  describe(`When an expired token which can be refreshed is provided`, function() {
216
257
  describe('When the refresh is available in time', function() {
217
258
  testApiSuccessAndFailure(async function(apiSucceeds) {
218
- scenario.setConfig(makeUid2Token(initialToken, true, true));
219
- respondAfterDelay(auctionDelayMs / 10);
259
+ scenario.setConfig(apiHelpers.makeTokenResponse(initialToken, true, true));
260
+ apiHelpers.respondAfterDelay(auctionDelayMs / 10);
220
261
  const bid = await runAuction();
221
262
 
222
- if (apiSucceeds) expectRefreshedToken(bid);
263
+ if (apiSucceeds) expectToken(bid, refreshedToken);
223
264
  else expectNoIdentity(bid);
224
265
  }, 'it should be used in the auction', 'the auction should have no uid2');
225
266
 
226
267
  testApiSuccessAndFailure(async function(apiSucceeds) {
227
- scenario.setConfig(makeUid2Token(initialToken, true, true));
228
- respondAfterDelay(auctionDelayMs / 10);
268
+ scenario.setConfig(apiHelpers.makeTokenResponse(initialToken, true, true));
269
+ apiHelpers.respondAfterDelay(auctionDelayMs / 10);
229
270
 
230
271
  await runAuction();
231
272
  if (apiSucceeds) {
232
- expectModuleCookieToContain(initialToken, refreshedToken);
273
+ expectModuleStorageToContain(initialToken, refreshedToken);
233
274
  } else {
234
- expectModuleCookieEmptyOrMissing();
275
+ expectModuleStorageEmptyOrMissing();
235
276
  }
236
- }, 'the refreshed token should be stored in the module cookie', 'the module cookie should not be set');
277
+ }, 'the refreshed token should be stored in the module storage', 'the module storage should not be set');
237
278
  });
238
279
  describe(`when the response doesn't arrive before the auction timer`, function() {
239
280
  testApiSuccessAndFailure(async function() {
240
- scenario.setConfig(makeUid2Token(initialToken, true, true));
281
+ scenario.setConfig(apiHelpers.makeTokenResponse(initialToken, true, true));
241
282
  const bid = await runAuction();
242
283
  expectNoIdentity(bid);
243
284
  }, 'it should run the auction');
244
285
 
245
286
  testApiSuccessAndFailure(async function(apiSucceeds) {
246
- scenario.setConfig(makeUid2Token(initialToken, true, true));
247
- const promise = respondAfterDelay(auctionDelayMs * 2);
287
+ scenario.setConfig(apiHelpers.makeTokenResponse(initialToken, true, true));
288
+ const promise = apiHelpers.respondAfterDelay(auctionDelayMs * 2);
248
289
 
249
290
  const bid = await runAuction();
250
291
  expectNoIdentity(bid);
251
292
  expectGlobalToHaveNoUid2();
252
293
  await promise;
253
- if (apiSucceeds) expectGlobalToHaveRefreshedIdentity();
294
+ if (apiSucceeds) expectGlobalToHaveToken(refreshedToken);
254
295
  else expectGlobalToHaveNoUid2();
255
296
  }, 'it should update the userId after the auction', 'there should be no global identity');
256
297
  })
257
298
  describe('and there is a refreshed token in the module cookie', function() {
258
299
  it('the refreshed value from the cookie is used', async function() {
259
- const initialIdentity = makeUid2Token(initialToken, true, true);
260
- const refreshedIdentity = makeUid2Token(refreshedToken);
300
+ const initialIdentity = apiHelpers.makeTokenResponse(initialToken, true, true);
301
+ const refreshedIdentity = apiHelpers.makeTokenResponse(refreshedToken);
261
302
  const moduleCookie = {originalToken: initialIdentity, latestToken: refreshedIdentity};
262
- coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), getFutureCookieExpiry());
303
+ coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry());
263
304
  scenario.setConfig(initialIdentity);
264
305
 
265
306
  const bid = await runAuction();
266
- expectRefreshedToken(bid);
307
+ expectToken(bid, refreshedToken);
267
308
  });
268
309
  })
269
310
  });
270
311
 
271
312
  describe(`When a current token is provided`, function() {
272
- beforeEach(function() {
273
- scenario.setConfig(makeUid2Token());
274
- });
275
-
276
313
  it('it should use the token in the auction', async function() {
314
+ scenario.setConfig(apiHelpers.makeTokenResponse(initialToken));
277
315
  const bid = await runAuction();
278
- expectInitialToken(bid);
316
+ expectToken(bid, initialToken);
279
317
  });
318
+
319
+ it('and GDPR applies, the token should not be used', async function() {
320
+ setGdprApplies();
321
+ scenario.setConfig(apiHelpers.makeTokenResponse(initialToken));
322
+ const bid = await runAuction();
323
+ expectNoIdentity(bid);
324
+ })
280
325
  });
281
326
 
282
327
  describe(`When a current token which should be refreshed is provided, and the auction is set to run immediately`, function() {
283
328
  beforeEach(function() {
284
- scenario.setConfig(makeUid2Token(initialToken, true), {auctionDelay: 0, syncDelay: 1});
329
+ scenario.setConfig(apiHelpers.makeTokenResponse(initialToken, true), {auctionDelay: 0, syncDelay: 1});
285
330
  });
286
331
  testApiSuccessAndFailure(async function() {
287
- respondAfterDelay(10);
332
+ apiHelpers.respondAfterDelay(10);
288
333
  const bid = await runAuction();
289
- expectInitialToken(bid);
334
+ expectToken(bid, initialToken);
290
335
  }, 'it should not be refreshed before the auction runs');
291
336
 
292
337
  testApiSuccessAndFailure(async function(success) {
293
- const promise = respondAfterDelay(1);
338
+ const promise = apiHelpers.respondAfterDelay(1);
294
339
  await runAuction();
295
340
  await promise;
296
341
  if (success) {
297
- expectModuleCookieToContain(initialToken, refreshedToken);
342
+ expectModuleStorageToContain(initialToken, refreshedToken);
298
343
  } else {
299
- expectModuleCookieToContain(initialToken, initialToken);
344
+ expectModuleStorageToContain(initialToken, initialToken);
300
345
  }
301
346
  }, 'the refreshed token should be stored in the module cookie after the auction runs', 'the module cookie should only have the original token');
302
347
 
303
348
  it('it should use the current token in the auction', async function() {
304
349
  const bid = await runAuction();
305
- expectInitialToken(bid);
350
+ expectToken(bid, initialToken);
306
351
  });
307
352
  });
308
353
  });
@@ -41,7 +41,9 @@ const videoBidReq = [{
41
41
  },
42
42
  mediaTypes: {video: {
43
43
  context: 'outstream',
44
- playerSize: [640, 480]
44
+ playerSize: [640, 480],
45
+ placement: 1,
46
+ plcmt: 1
45
47
  }},
46
48
  sizes: [[300, 250], [300, 600]],
47
49
  bidId: '263be71e91dd9d',
@@ -184,6 +186,31 @@ const bidderReqCcpaAndGdpr = {
184
186
  uspConsent: 'NY12'
185
187
  };
186
188
 
189
+ const bidderReqGpp = {
190
+ refererInfo: {
191
+ topmostLocation: 'http://prebid.org/dev-docs/bidder-adaptor.html'
192
+ },
193
+ gppConsent: {
194
+ gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN',
195
+ applicableSections: [7]
196
+ }
197
+ };
198
+
199
+ const bidderReqFullGppCcpaGdpr = {
200
+ refererInfo: {
201
+ topmostLocation: 'http://prebid.org/dev-docs/bidder-adaptor.html'
202
+ },
203
+ gppConsent: {
204
+ gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN',
205
+ applicableSections: [7]
206
+ },
207
+ gdprConsent: {
208
+ gdprApplies: true,
209
+ consentString: 'gdprConsent'
210
+ },
211
+ uspConsent: '1YNN'
212
+ };
213
+
187
214
  const validBidRes = {
188
215
  ad: '<div>Hello</div>',
189
216
  publisherId: 12345,
@@ -381,6 +408,31 @@ describe('Undertone Adapter', () => {
381
408
  expect(request.url).to.equal(REQ_URL);
382
409
  expect(request.method).to.equal('POST');
383
410
  });
411
+ it(`should have gppConsent fields`, function () {
412
+ const request = spec.buildRequests(bidReq, bidderReqGpp);
413
+ const domainStart = bidderReq.refererInfo.topmostLocation.indexOf('//');
414
+ const domainEnd = bidderReq.refererInfo.topmostLocation.indexOf('/', domainStart + 2);
415
+ const domain = bidderReq.refererInfo.topmostLocation.substring(domainStart + 2, domainEnd);
416
+ const gppStr = bidderReqGpp.gppConsent.gppString;
417
+ const gppSid = bidderReqGpp.gppConsent.applicableSections;
418
+ const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&gpp=${gppStr}&gpp_sid=${gppSid}`;
419
+ expect(request.url).to.equal(REQ_URL);
420
+ expect(request.method).to.equal('POST');
421
+ });
422
+ it(`should have gpp, ccpa and gdpr fields`, function () {
423
+ const request = spec.buildRequests(bidReq, bidderReqFullGppCcpaGdpr);
424
+ const domainStart = bidderReq.refererInfo.topmostLocation.indexOf('//');
425
+ const domainEnd = bidderReq.refererInfo.topmostLocation.indexOf('/', domainStart + 2);
426
+ const domain = bidderReq.refererInfo.topmostLocation.substring(domainStart + 2, domainEnd);
427
+ const gppStr = bidderReqFullGppCcpaGdpr.gppConsent.gppString;
428
+ const gppSid = bidderReqFullGppCcpaGdpr.gppConsent.applicableSections;
429
+ const ccpa = bidderReqFullGppCcpaGdpr.uspConsent;
430
+ const gdpr = bidderReqFullGppCcpaGdpr.gdprConsent.gdprApplies ? 1 : 0;
431
+ const gdprStr = bidderReqFullGppCcpaGdpr.gdprConsent.consentString;
432
+ const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&gdpr=${gdpr}&gdprstr=${gdprStr}&ccpa=${ccpa}&gpp=${gppStr}&gpp_sid=${gppSid}`;
433
+ expect(request.url).to.equal(REQ_URL);
434
+ expect(request.method).to.equal('POST');
435
+ });
384
436
  it('should have all relevant fields', function () {
385
437
  const request = spec.buildRequests(bidReq, bidderReq);
386
438
  const bid1 = JSON.parse(request.data)['x-ut-hb-params'][0];
@@ -409,10 +461,14 @@ describe('Undertone Adapter', () => {
409
461
  expect(bidVideo.video.playbackMethod).to.equal(2);
410
462
  expect(bidVideo.video.maxDuration).to.equal(30);
411
463
  expect(bidVideo.video.skippable).to.equal(true);
464
+ expect(bidVideo.video.placement).to.equal(1);
465
+ expect(bidVideo.video.plcmt).to.equal(1);
412
466
 
413
467
  expect(bidVideo2.video.skippable).to.equal(null);
414
468
  expect(bidVideo2.video.maxDuration).to.equal(null);
415
469
  expect(bidVideo2.video.playbackMethod).to.equal(null);
470
+ expect(bidVideo2.video.placement).to.equal(null);
471
+ expect(bidVideo2.video.plcmt).to.equal(null);
416
472
  });
417
473
  it('should send all userIds data to server', function () {
418
474
  const request = spec.buildRequests(bidReqUserIds, bidderReq);