prebid.js 8.8.0 → 8.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.
- package/dist/1plusXRtdProvider.js +1 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adWMGAnalyticsAdapter.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adkernelAdnAnalyticsAdapter.js +1 -1
- package/dist/adlooxAdServerVideo.js +1 -1
- package/dist/adlooxRtdProvider.js +1 -1
- package/dist/admixerIdSystem.js +1 -1
- package/dist/adnuntiusRtdProvider.js +1 -1
- package/dist/adpartnerBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adqueryIdSystem.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adriverIdSystem.js +1 -1
- package/dist/adtelligentIdSystem.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgAnalyticsAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adxpremiumAnalyticsAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/aidemBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/akamaiDapRtdProvider.js +1 -1
- package/dist/alkimiBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/analyticsAdapter.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/atsAnalyticsAdapter.js +1 -1
- package/dist/automatadBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/bidwatchAnalyticsAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/brightcomSSPBidAdapter.js +1 -1
- package/dist/britepoolIdSystem.js +1 -1
- package/dist/browsiRtdProvider.js +1 -1
- package/dist/byDataAnalyticsAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/categoryTranslation.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/colossussspBidAdapter.js +1 -1
- package/dist/concertAnalyticsAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectIdSystem.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/criteoIdSystem.js +1 -1
- package/dist/currency.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dacIdSystem.js +1 -1
- package/dist/dailyhuntBidAdapter.js +1 -1
- package/dist/datablocksBidAdapter.js +1 -1
- package/dist/dgkeywordRtdProvider.js +1 -1
- package/dist/dmdIdSystem.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningAnalyticsAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/fabrickIdSystem.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/fintezaAnalyticsAdapter.js +1 -1
- package/dist/fledgeForGpt.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/genericAnalyticsAdapter.js +1 -1
- package/dist/geoedgeRtdProvider.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/gnetBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/growthCodeAnalyticsAdapter.js +1 -1
- package/dist/growthCodeIdSystem.js +1 -1
- package/dist/growthCodeRtdProvider.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hadronAnalyticsAdapter.js +1 -1
- package/dist/hadronIdSystem.js +1 -1
- package/dist/hadronRtdProvider.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/iasRtdProvider.js +1 -1
- package/dist/id5AnalyticsAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/idImportLibrary.js +1 -1
- package/dist/identityLinkIdSystem.js +1 -1
- package/dist/imRtdProvider.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/impactifyBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/imuIdSystem.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/intentIqIdSystem.js +1 -1
- package/dist/invisiblyAnalyticsAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/jixieBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/jwplayerRtdProvider.js +1 -1
- package/dist/kargoAnalyticsAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/kinessoIdSystem.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/konduitWrapper.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/limelightDigitalBidAdapter.js +1 -1
- package/dist/liveIntentAnalyticsAdapter.js +1 -1
- package/dist/liveIntentIdSystem.js +1 -1
- package/dist/livewrappedAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/lotamePanoramaIdSystem.js +1 -1
- package/dist/luponmediaBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/mantisBidAdapter.js +1 -1
- package/dist/marsmediaAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/medianetAnalyticsAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/merkleIdSystem.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/mgidRtdProvider.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/mspa.js +1 -1
- package/dist/mwOpenLinkIdSystem.js +1 -1
- package/dist/naveggIdSystem.js +1 -1
- package/dist/neuwoRtdProvider.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +240 -240
- package/dist/novatiqIdSystem.js +1 -1
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/open8BidAdapter.js +1 -1
- package/dist/operaadsIdSystem.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/optimeraRtdProvider.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/oxxionAnalyticsAdapter.js +1 -1
- package/dist/oxxionRtdProvider.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +2 -2
- package/dist/prebidServerBidAdapter.js +1 -1
- package/dist/prebidmanagerAnalyticsAdapter.js +1 -1
- package/dist/priceFloors.js +1 -1
- package/dist/prismaBidAdapter.js +1 -1
- package/dist/pubgeniusBidAdapter.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticAnalyticsAdapter.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pubxaiAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/qwarryBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/reconciliationRtdProvider.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/relevadRtdProvider.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rivrAnalyticsAdapter.js +1 -1
- package/dist/roxotAnalyticsAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/scaleableAnalyticsAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/silverpushBidAdapter.js +1 -1
- package/dist/sirdataRtdProvider.js +1 -1
- package/dist/slimcutBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smartyadsBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiAnalyticsAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/staqAnalyticsAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/taboolaBidAdapter.js +1 -1
- package/dist/talkadsBidAdapter.js +1 -1
- package/dist/tapadIdSystem.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/teadsIdSystem.js +1 -1
- package/dist/terceptAnalyticsAdapter.js +1 -1
- package/dist/timeoutRtdProvider.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/unifiedIdSystem.js +1 -1
- package/dist/verizonMediaIdSystem.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vrtcalBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/weboramaRtdProvider.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/dist/yuktamediaAnalyticsAdapter.js +1 -1
- package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
- package/dist/zeta_global_sspBidAdapter.js +1 -1
- package/integrationExamples/gpt/growthcode.html +3 -12
- package/libraries/mspa/activityControls.js +3 -1
- package/modules/adagioBidAdapter.js +11 -3
- package/modules/concertBidAdapter.js +1 -0
- package/modules/fledgeForGpt.js +17 -4
- package/modules/fledgeForGpt.md +17 -10
- package/modules/geoedgeRtdProvider.js +1 -5
- package/modules/growthCodeAnalyticsAdapter.js +7 -4
- package/modules/growthCodeAnalyticsAdapter.md +1 -7
- package/modules/nexx360BidAdapter.js +7 -1
- package/modules/prebidServerBidAdapter/index.js +8 -2
- package/modules/pubmaticAnalyticsAdapter.js +16 -3
- package/package.json +1 -1
- package/src/adapters/bidderFactory.js +14 -5
- package/src/ajax.js +126 -87
- package/src/constants.json +8 -2
- package/src/native.js +12 -1
- package/test/mocks/xhr.js +256 -9
- package/test/spec/libraries/mspa/activityControls_spec.js +6 -0
- package/test/spec/modules/adagioBidAdapter_spec.js +15 -0
- package/test/spec/modules/adlooxAdServerVideo_spec.js +1 -5
- package/test/spec/modules/adlooxRtdProvider_spec.js +1 -5
- package/test/spec/modules/categoryTranslation_spec.js +7 -9
- package/test/spec/modules/concertBidAdapter_spec.js +1 -1
- package/test/spec/modules/conversantAnalyticsAdapter_spec.js +3 -5
- package/test/spec/modules/currency_spec.js +2 -2
- package/test/spec/modules/dmdIdSystem_spec.js +2 -2
- package/test/spec/modules/euidIdSystem_spec.js +10 -9
- package/test/spec/modules/feedadBidAdapter_spec.js +1 -1
- package/test/spec/modules/fledge_spec.js +117 -43
- package/test/spec/modules/geoedgeRtdProvider_spec.js +11 -18
- package/test/spec/modules/greenbidsRtdProvider_spec.js +3 -12
- package/test/spec/modules/growthCodeAnalyticsAdapter_spec.js +0 -1
- package/test/spec/modules/hadronIdSystem_spec.js +1 -1
- package/test/spec/modules/id5AnalyticsAdapter_spec.js +1 -7
- package/test/spec/modules/id5IdSystem_spec.js +25 -25
- package/test/spec/modules/identityLinkIdSystem_spec.js +0 -2
- package/test/spec/modules/intentIqIdSystem_spec.js +0 -2
- package/test/spec/modules/invisiblyAnalyticsAdapter_spec.js +2 -6
- package/test/spec/modules/jwplayerRtdProvider_spec.js +26 -28
- package/test/spec/modules/magniteAnalyticsAdapter_spec.js +2 -2
- package/test/spec/modules/mgidRtdProvider_spec.js +1 -5
- package/test/spec/modules/nexx360BidAdapter_spec.js +48 -1
- package/test/spec/modules/oguryBidAdapter_spec.js +5 -19
- package/test/spec/modules/ooloAnalyticsAdapter_spec.js +1 -1
- package/test/spec/modules/prebidServerBidAdapter_spec.js +33 -2
- package/test/spec/modules/priceFloors_spec.js +33 -37
- package/test/spec/modules/publinkIdSystem_spec.js +1 -1
- package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +102 -18
- package/test/spec/modules/pubwiseAnalyticsAdapter_spec.js +2 -8
- package/test/spec/modules/teadsIdSystem_spec.js +1 -1
- package/test/spec/modules/uid2IdSystem_helpers.js +5 -5
- package/test/spec/modules/uid2IdSystem_spec.js +24 -24
- package/test/spec/modules/userId_spec.js +1 -1
- package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +2 -5
- package/test/spec/native_spec.js +15 -2
- package/test/spec/unit/core/ajax_spec.js +403 -0
- package/test/spec/unit/core/bidderFactory_spec.js +80 -8
- package/test/spec/videoCache_spec.js +4 -4
|
@@ -283,7 +283,7 @@ function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) {
|
|
|
283
283
|
'ocpm': bid.bidResponse ? (bid.bidResponse.originalCpm || 0) : 0,
|
|
284
284
|
'ocry': bid.bidResponse ? (bid.bidResponse.originalCurrency || CURRENCY_USD) : CURRENCY_USD,
|
|
285
285
|
'piid': bid.bidResponse ? (bid.bidResponse.partnerImpId || EMPTY_STRING) : EMPTY_STRING,
|
|
286
|
-
'frv': (
|
|
286
|
+
'frv': (bid.bidResponse ? (bid.bidResponse.floorData ? bid.bidResponse.floorData.floorRuleValue : undefined) : undefined),
|
|
287
287
|
'md': bid.bidResponse ? getMetadata(bid.bidResponse.meta) : undefined
|
|
288
288
|
});
|
|
289
289
|
});
|
|
@@ -319,6 +319,17 @@ function getTgId() {
|
|
|
319
319
|
return 0;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
+
function getFloorFetchStatus(floorData) {
|
|
323
|
+
if (!floorData?.floorRequestData) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
const { location, fetchStatus } = floorData?.floorRequestData;
|
|
327
|
+
const isDataValid = location !== CONSTANTS.FLOOR_VALUES.NO_DATA;
|
|
328
|
+
const isFetchSuccessful = location === CONSTANTS.FLOOR_VALUES.FETCH && fetchStatus === CONSTANTS.FLOOR_VALUES.SUCCESS;
|
|
329
|
+
const isAdUnitOrSetConfig = location === CONSTANTS.FLOOR_VALUES.AD_UNIT || location === CONSTANTS.FLOOR_VALUES.SET_CONFIG;
|
|
330
|
+
return isDataValid && (isAdUnitOrSetConfig || isFetchSuccessful);
|
|
331
|
+
}
|
|
332
|
+
|
|
322
333
|
function executeBidsLoggerCall(e, highestCpmBids) {
|
|
323
334
|
let auctionId = e.auctionId;
|
|
324
335
|
let referrer = config.getConfig('pageUrl') || cache.auctions[auctionId].referer || '';
|
|
@@ -326,6 +337,8 @@ function executeBidsLoggerCall(e, highestCpmBids) {
|
|
|
326
337
|
let floorData = auctionCache.floorData;
|
|
327
338
|
let outputObj = { s: [] };
|
|
328
339
|
let pixelURL = END_POINT_BID_LOGGER;
|
|
340
|
+
// will return true if floor data is present.
|
|
341
|
+
let fetchStatus = getFloorFetchStatus(auctionCache.floorData);
|
|
329
342
|
|
|
330
343
|
if (!auctionCache) {
|
|
331
344
|
return;
|
|
@@ -347,7 +360,7 @@ function executeBidsLoggerCall(e, highestCpmBids) {
|
|
|
347
360
|
outputObj['dvc'] = {'plt': getDevicePlatform()};
|
|
348
361
|
outputObj['tgid'] = getTgId();
|
|
349
362
|
|
|
350
|
-
if (floorData) {
|
|
363
|
+
if (floorData && fetchStatus) {
|
|
351
364
|
outputObj['fmv'] = floorData.floorRequestData ? floorData.floorRequestData.modelVersion || undefined : undefined;
|
|
352
365
|
outputObj['ft'] = floorData.floorResponseData ? (floorData.floorResponseData.enforcements.enforceJS == false ? 0 : 1) : undefined;
|
|
353
366
|
}
|
|
@@ -362,7 +375,7 @@ function executeBidsLoggerCall(e, highestCpmBids) {
|
|
|
362
375
|
'mt': getAdUnitAdFormats(origAdUnit),
|
|
363
376
|
'sz': getSizesForAdUnit(adUnit, adUnitId),
|
|
364
377
|
'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)),
|
|
365
|
-
'fskp': floorData ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined,
|
|
378
|
+
'fskp': (floorData && fetchStatus) ? (floorData.floorRequestData ? (floorData.floorRequestData.skipped == false ? 0 : 1) : undefined) : undefined,
|
|
366
379
|
};
|
|
367
380
|
slotsArray.push(slotObject);
|
|
368
381
|
return slotsArray;
|
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@ import {useMetrics} from '../utils/perfMetrics.js';
|
|
|
25
25
|
import {isActivityAllowed} from '../activities/rules.js';
|
|
26
26
|
import {activityParams} from '../activities/activityParams.js';
|
|
27
27
|
import {MODULE_TYPE_BIDDER} from '../activities/modules.js';
|
|
28
|
-
import {ACTIVITY_TRANSMIT_TID} from '../activities/activities.js';
|
|
28
|
+
import {ACTIVITY_TRANSMIT_TID, ACTIVITY_TRANSMIT_UFPD} from '../activities/activities.js';
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* This file aims to support Adapters during the Prebid 0.x -> 1.x transition.
|
|
@@ -454,6 +454,15 @@ export const processBidderRequests = hook('sync', function (spec, bids, bidderRe
|
|
|
454
454
|
onRequest(request);
|
|
455
455
|
|
|
456
456
|
const networkDone = requestMetrics.startTiming('net');
|
|
457
|
+
|
|
458
|
+
function getOptions(defaults) {
|
|
459
|
+
const ro = request.options;
|
|
460
|
+
return Object.assign(defaults, ro, {
|
|
461
|
+
browsingTopics: ro?.hasOwnProperty('browsingTopics') && !ro.browsingTopics
|
|
462
|
+
? false
|
|
463
|
+
: isActivityAllowed(ACTIVITY_TRANSMIT_UFPD, activityParams(MODULE_TYPE_BIDDER, spec.code))
|
|
464
|
+
})
|
|
465
|
+
}
|
|
457
466
|
switch (request.method) {
|
|
458
467
|
case 'GET':
|
|
459
468
|
ajax(
|
|
@@ -463,10 +472,10 @@ export const processBidderRequests = hook('sync', function (spec, bids, bidderRe
|
|
|
463
472
|
error: onFailure
|
|
464
473
|
},
|
|
465
474
|
undefined,
|
|
466
|
-
|
|
475
|
+
getOptions({
|
|
467
476
|
method: 'GET',
|
|
468
477
|
withCredentials: true
|
|
469
|
-
}
|
|
478
|
+
})
|
|
470
479
|
);
|
|
471
480
|
break;
|
|
472
481
|
case 'POST':
|
|
@@ -477,11 +486,11 @@ export const processBidderRequests = hook('sync', function (spec, bids, bidderRe
|
|
|
477
486
|
error: onFailure
|
|
478
487
|
},
|
|
479
488
|
typeof request.data === 'string' ? request.data : JSON.stringify(request.data),
|
|
480
|
-
|
|
489
|
+
getOptions({
|
|
481
490
|
method: 'POST',
|
|
482
491
|
contentType: 'text/plain',
|
|
483
492
|
withCredentials: true
|
|
484
|
-
}
|
|
493
|
+
})
|
|
485
494
|
);
|
|
486
495
|
break;
|
|
487
496
|
default:
|
package/src/ajax.js
CHANGED
|
@@ -1,99 +1,138 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {config} from './config.js';
|
|
2
|
+
import {buildUrl, logError, parseUrl} from './utils.js';
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
export const dep = {
|
|
5
|
+
fetch: window.fetch.bind(window),
|
|
6
|
+
makeRequest: (r, o) => new Request(r, o),
|
|
7
|
+
timeout(timeout, resource) {
|
|
8
|
+
const ctl = new AbortController();
|
|
9
|
+
let cancelTimer = setTimeout(() => {
|
|
10
|
+
ctl.abort();
|
|
11
|
+
logError(`Request timeout after ${timeout}ms`, resource);
|
|
12
|
+
cancelTimer = null;
|
|
13
|
+
}, timeout);
|
|
14
|
+
return {
|
|
15
|
+
signal: ctl.signal,
|
|
16
|
+
done() {
|
|
17
|
+
cancelTimer && clearTimeout(cancelTimer)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const GET = 'GET';
|
|
24
|
+
const POST = 'POST';
|
|
25
|
+
const CTYPE = 'Content-Type';
|
|
5
26
|
|
|
6
27
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* @param url string url
|
|
11
|
-
* @param callback {object | function} callback
|
|
12
|
-
* @param data mixed data
|
|
13
|
-
* @param options object
|
|
28
|
+
* transform legacy `ajax` parameters into a fetch request.
|
|
29
|
+
* @returns {Request}
|
|
14
30
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
export function toFetchRequest(url, data, options = {}) {
|
|
32
|
+
const method = options.method || (data ? POST : GET);
|
|
33
|
+
if (method === GET && data) {
|
|
34
|
+
const urlInfo = parseUrl(url, options);
|
|
35
|
+
Object.assign(urlInfo.search, data);
|
|
36
|
+
url = buildUrl(urlInfo);
|
|
37
|
+
}
|
|
38
|
+
const headers = new Headers(options.customHeaders);
|
|
39
|
+
headers.set(CTYPE, options.contentType || 'text/plain');
|
|
40
|
+
const rqOpts = {
|
|
41
|
+
method,
|
|
42
|
+
headers
|
|
43
|
+
}
|
|
44
|
+
if (method !== GET && data) {
|
|
45
|
+
rqOpts.body = data;
|
|
46
|
+
}
|
|
47
|
+
if (options.withCredentials) {
|
|
48
|
+
rqOpts.credentials = 'include';
|
|
49
|
+
}
|
|
50
|
+
if (options.browsingTopics && isSecureContext) {
|
|
51
|
+
// the Request constructor will throw an exception if the browser supports topics
|
|
52
|
+
// but we're not in a secure context
|
|
53
|
+
rqOpts.browsingTopics = true;
|
|
54
|
+
}
|
|
55
|
+
return dep.makeRequest(url, rqOpts);
|
|
56
|
+
}
|
|
33
57
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Return a version of `fetch` that automatically cancels requests after `timeout` milliseconds.
|
|
60
|
+
*
|
|
61
|
+
* If provided, `request` and `done` should be functions accepting a single argument.
|
|
62
|
+
* `request` is invoked at the beginning of each request, and `done` at the end; both are passed its origin.
|
|
63
|
+
*
|
|
64
|
+
* @returns {function(*, {}?): Promise<Response>}
|
|
65
|
+
*/
|
|
66
|
+
export function fetcherFactory(timeout = 3000, {request, done} = {}) {
|
|
67
|
+
let fetcher = (resource, options) => {
|
|
68
|
+
let to;
|
|
69
|
+
if (timeout != null && options?.signal == null && !config.getConfig('disableAjaxTimeout')) {
|
|
70
|
+
to = dep.timeout(timeout, resource);
|
|
71
|
+
options = Object.assign({signal: to.signal}, options);
|
|
72
|
+
}
|
|
73
|
+
let pm = dep.fetch(resource, options);
|
|
74
|
+
if (to?.done != null) pm = pm.finally(to.done);
|
|
75
|
+
return pm;
|
|
76
|
+
};
|
|
37
77
|
|
|
38
|
-
|
|
78
|
+
if (request != null || done != null) {
|
|
79
|
+
fetcher = ((fetch) => function (resource, options) {
|
|
80
|
+
const origin = new URL(resource?.url == null ? resource : resource.url, document.location).origin;
|
|
81
|
+
let req = fetch(resource, options);
|
|
82
|
+
request && request(origin);
|
|
83
|
+
if (done) req = req.finally(() => done(origin));
|
|
84
|
+
return req;
|
|
85
|
+
})(fetcher);
|
|
86
|
+
}
|
|
87
|
+
return fetcher;
|
|
88
|
+
}
|
|
39
89
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
90
|
+
function toXHR({status, statusText = '', headers, url}, responseText) {
|
|
91
|
+
let xml = 0;
|
|
92
|
+
return {
|
|
93
|
+
readyState: XMLHttpRequest.DONE,
|
|
94
|
+
status,
|
|
95
|
+
statusText,
|
|
96
|
+
responseText,
|
|
97
|
+
response: responseText,
|
|
98
|
+
responseType: '',
|
|
99
|
+
responseURL: url,
|
|
100
|
+
get responseXML() {
|
|
101
|
+
if (xml === 0) {
|
|
102
|
+
try {
|
|
103
|
+
xml = new DOMParser().parseFromString(responseText, headers?.get(CTYPE)?.split(';')?.[0])
|
|
104
|
+
} catch (e) {
|
|
105
|
+
xml = null;
|
|
106
|
+
logError(e);
|
|
51
107
|
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// Disabled timeout temporarily to avoid xhr failed requests. https://github.com/prebid/Prebid.js/issues/2648
|
|
55
|
-
if (!config.getConfig('disableAjaxTimeout')) {
|
|
56
|
-
x.ontimeout = function () {
|
|
57
|
-
logError(' xhr timeout after ', x.timeout, 'ms');
|
|
58
|
-
};
|
|
59
108
|
}
|
|
109
|
+
return xml;
|
|
110
|
+
},
|
|
111
|
+
getResponseHeader: (header) => headers?.has(header) ? headers.get(header) : null,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
60
114
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
x.withCredentials = true;
|
|
76
|
-
}
|
|
77
|
-
_each(options.customHeaders, (value, header) => {
|
|
78
|
-
x.setRequestHeader(header, value);
|
|
79
|
-
});
|
|
80
|
-
if (options.preflight) {
|
|
81
|
-
x.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
82
|
-
}
|
|
83
|
-
x.setRequestHeader('Content-Type', options.contentType || 'text/plain');
|
|
84
|
-
|
|
85
|
-
if (typeof request === 'function') {
|
|
86
|
-
request(parser.origin);
|
|
87
|
-
}
|
|
115
|
+
/**
|
|
116
|
+
* attach legacy `ajax` callbacks to a fetch promise.
|
|
117
|
+
*/
|
|
118
|
+
export function attachCallbacks(fetchPm, callback) {
|
|
119
|
+
const {success, error} = typeof callback === 'object' && callback != null ? callback : {
|
|
120
|
+
success: typeof callback === 'function' ? callback : () => null,
|
|
121
|
+
error: (e, x) => logError('Network error', e, x)
|
|
122
|
+
};
|
|
123
|
+
fetchPm.then(response => response.text().then((responseText) => [response, responseText]))
|
|
124
|
+
.then(([response, responseText]) => {
|
|
125
|
+
const xhr = toXHR(response, responseText);
|
|
126
|
+
response.ok || response.status === 304 ? success(responseText, xhr) : error(response.statusText, xhr);
|
|
127
|
+
}, () => error('', toXHR({status: 0}, '')));
|
|
128
|
+
}
|
|
88
129
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
} catch (error) {
|
|
95
|
-
logError('xhr construction', error);
|
|
96
|
-
typeof callback === 'object' && callback !== null && callback.error(error);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
130
|
+
export function ajaxBuilder(timeout = 3000, {request, done} = {}) {
|
|
131
|
+
const fetcher = fetcherFactory(timeout, {request, done});
|
|
132
|
+
return function (url, callback, data, options = {}) {
|
|
133
|
+
attachCallbacks(fetcher(toFetchRequest(url, data, options)), callback);
|
|
134
|
+
};
|
|
99
135
|
}
|
|
136
|
+
|
|
137
|
+
export const ajax = ajaxBuilder();
|
|
138
|
+
export const fetch = fetcherFactory();
|
package/src/constants.json
CHANGED
|
@@ -163,11 +163,17 @@
|
|
|
163
163
|
"MAIN": 3
|
|
164
164
|
},
|
|
165
165
|
"NATIVE_KEYS_THAT_ARE_NOT_ASSETS": [
|
|
166
|
-
"privacyLink",
|
|
167
166
|
"clickUrl",
|
|
168
167
|
"sendTargetingKeys",
|
|
169
168
|
"adTemplate",
|
|
170
169
|
"rendererUrl",
|
|
171
170
|
"type"
|
|
172
|
-
]
|
|
171
|
+
],
|
|
172
|
+
"FLOOR_VALUES": {
|
|
173
|
+
"NO_DATA": "noData",
|
|
174
|
+
"AD_UNIT": "adUnit",
|
|
175
|
+
"SET_CONFIG": "setConfig",
|
|
176
|
+
"FETCH": "fetch",
|
|
177
|
+
"SUCCESS": "success"
|
|
178
|
+
}
|
|
173
179
|
}
|
package/src/native.js
CHANGED
|
@@ -480,6 +480,11 @@ export function toOrtbNativeRequest(legacyNativeAssets) {
|
|
|
480
480
|
continue;
|
|
481
481
|
}
|
|
482
482
|
|
|
483
|
+
if (key === 'privacyLink') {
|
|
484
|
+
ortb.privacy = 1;
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
|
|
483
488
|
const asset = legacyNativeAssets[key];
|
|
484
489
|
let required = 0;
|
|
485
490
|
if (asset.required && isBoolean(asset.required)) {
|
|
@@ -623,6 +628,9 @@ export function fromOrtbNativeRequest(openRTBRequest) {
|
|
|
623
628
|
oldNativeObject[prebidAssetName].len = asset.data.len;
|
|
624
629
|
}
|
|
625
630
|
}
|
|
631
|
+
if (openRTBRequest.privacy) {
|
|
632
|
+
oldNativeObject.privacyLink = { required: false };
|
|
633
|
+
}
|
|
626
634
|
// video was not supported by old prebid assets
|
|
627
635
|
}
|
|
628
636
|
return oldNativeObject;
|
|
@@ -696,8 +704,11 @@ export function legacyPropertiesToOrtbNative(legacyNative) {
|
|
|
696
704
|
// in general, native trackers seem to be neglected and/or broken
|
|
697
705
|
response.jstracker = Array.isArray(value) ? value.join('') : value;
|
|
698
706
|
break;
|
|
707
|
+
case 'privacyLink':
|
|
708
|
+
response.privacy = value;
|
|
709
|
+
break;
|
|
699
710
|
}
|
|
700
|
-
})
|
|
711
|
+
});
|
|
701
712
|
return response;
|
|
702
713
|
}
|
|
703
714
|
|
package/test/mocks/xhr.js
CHANGED
|
@@ -1,12 +1,236 @@
|
|
|
1
1
|
import {getUniqueIdentifierStr} from '../../src/utils.js';
|
|
2
|
+
import {GreedyPromise} from '../../src/utils/promise.js';
|
|
3
|
+
import {fakeXhr} from 'nise';
|
|
4
|
+
import {dep} from 'src/ajax.js';
|
|
2
5
|
|
|
3
|
-
export
|
|
4
|
-
export
|
|
6
|
+
export const xhr = sinon.useFakeXMLHttpRequest();
|
|
7
|
+
export const server = mockFetchServer();
|
|
5
8
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* An (incomplete) replica of nise's fakeServer, but backing fetch used in ajax.js (rather than XHR).
|
|
11
|
+
*/
|
|
12
|
+
function mockFetchServer() {
|
|
13
|
+
const sandbox = sinon.createSandbox();
|
|
14
|
+
const bodies = new WeakMap();
|
|
15
|
+
const requests = [];
|
|
16
|
+
const {DONE, UNSENT} = XMLHttpRequest;
|
|
17
|
+
|
|
18
|
+
function makeRequest(resource, options) {
|
|
19
|
+
const requestBody = options?.body || bodies.get(resource);
|
|
20
|
+
const request = new Request(resource, options);
|
|
21
|
+
bodies.set(request, requestBody);
|
|
22
|
+
return request;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function mockXHR(resource, options) {
|
|
26
|
+
let resolve, reject;
|
|
27
|
+
const promise = new GreedyPromise((res, rej) => {
|
|
28
|
+
resolve = res;
|
|
29
|
+
reject = rej;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
function error(reason = new TypeError('Failed to fetch')) {
|
|
33
|
+
mockReq.status = 0;
|
|
34
|
+
reject(reason);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const request = makeRequest(resource, options);
|
|
38
|
+
request.signal.onabort = () => error(new DOMException('The user aborted a request'));
|
|
39
|
+
let responseHeaders;
|
|
40
|
+
|
|
41
|
+
const mockReq = {
|
|
42
|
+
fetch: {
|
|
43
|
+
request,
|
|
44
|
+
requestBody: bodies.get(request),
|
|
45
|
+
promise,
|
|
46
|
+
},
|
|
47
|
+
readyState: UNSENT,
|
|
48
|
+
url: request.url,
|
|
49
|
+
method: request.method,
|
|
50
|
+
requestBody: bodies.get(request),
|
|
51
|
+
status: 0,
|
|
52
|
+
statusText: '',
|
|
53
|
+
requestHeaders: new Proxy(request.headers, {
|
|
54
|
+
get(target, prop) {
|
|
55
|
+
return typeof prop === 'string' && target.has(prop) ? target.get(prop) : {}[prop];
|
|
56
|
+
},
|
|
57
|
+
has(target, prop) {
|
|
58
|
+
return typeof prop === 'string' && target.has(prop);
|
|
59
|
+
},
|
|
60
|
+
ownKeys(target) {
|
|
61
|
+
return Array.from(target.keys());
|
|
62
|
+
},
|
|
63
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
64
|
+
if (typeof prop === 'string' && target.has(prop)) {
|
|
65
|
+
return {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: false,
|
|
69
|
+
value: target.get(prop)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}),
|
|
74
|
+
withCredentials: request.credentials === 'include',
|
|
75
|
+
setStatus(status) {
|
|
76
|
+
// nise replaces invalid status with 200
|
|
77
|
+
status = typeof status === 'number' ? status : 200;
|
|
78
|
+
mockReq.status = status;
|
|
79
|
+
mockReq.statusText = fakeXhr.FakeXMLHttpRequest.statusCodes[status] || '';
|
|
80
|
+
},
|
|
81
|
+
setResponseHeaders(headers) {
|
|
82
|
+
responseHeaders = headers;
|
|
83
|
+
},
|
|
84
|
+
setResponseBody(body) {
|
|
85
|
+
if (mockReq.status === 0) {
|
|
86
|
+
error();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const resp = Object.defineProperties(new Response(body, {
|
|
90
|
+
status: mockReq.status,
|
|
91
|
+
statusText: mockReq.statusText,
|
|
92
|
+
headers: responseHeaders || {},
|
|
93
|
+
}), {
|
|
94
|
+
url: {
|
|
95
|
+
get: () => mockReq.fetch.request.url,
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
mockReq.readyState = DONE;
|
|
99
|
+
// tests expect respond() to run everything immediately,
|
|
100
|
+
// so make body available syncronously
|
|
101
|
+
resp.text = () => GreedyPromise.resolve(body || '');
|
|
102
|
+
Object.assign(mockReq.fetch, {
|
|
103
|
+
response: resp,
|
|
104
|
+
responseBody: body || ''
|
|
105
|
+
})
|
|
106
|
+
resolve(resp);
|
|
107
|
+
},
|
|
108
|
+
respond(status = 200, headers, body) {
|
|
109
|
+
mockReq.setStatus(status);
|
|
110
|
+
mockReq.setResponseHeaders(headers);
|
|
111
|
+
mockReq.setResponseBody(body);
|
|
112
|
+
},
|
|
113
|
+
error
|
|
114
|
+
};
|
|
115
|
+
return mockReq;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let enabled = false;
|
|
119
|
+
let timeoutsEnabled = false;
|
|
120
|
+
|
|
121
|
+
function enable() {
|
|
122
|
+
if (!enabled) {
|
|
123
|
+
sandbox.stub(dep, 'fetch').callsFake((resource, options) => {
|
|
124
|
+
const req = mockXHR(resource, options);
|
|
125
|
+
requests.push(req);
|
|
126
|
+
return req.fetch.promise;
|
|
127
|
+
});
|
|
128
|
+
sandbox.stub(dep, 'makeRequest').callsFake(makeRequest);
|
|
129
|
+
const timeout = dep.timeout;
|
|
130
|
+
sandbox.stub(dep, 'timeout').callsFake(function () {
|
|
131
|
+
if (timeoutsEnabled) {
|
|
132
|
+
return timeout.apply(null, arguments);
|
|
133
|
+
} else {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
enabled = true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
enable();
|
|
142
|
+
|
|
143
|
+
const responders = [];
|
|
144
|
+
|
|
145
|
+
function respondWith() {
|
|
146
|
+
let response, urlMatcher, methodMatcher;
|
|
147
|
+
urlMatcher = methodMatcher = () => true;
|
|
148
|
+
switch (arguments.length) {
|
|
149
|
+
case 1:
|
|
150
|
+
([response] = arguments);
|
|
151
|
+
break;
|
|
152
|
+
case 2:
|
|
153
|
+
([urlMatcher, response] = arguments);
|
|
154
|
+
break;
|
|
155
|
+
case 3:
|
|
156
|
+
([methodMatcher, urlMatcher, response] = arguments);
|
|
157
|
+
methodMatcher = ((toMatch) => (method) => method === toMatch)(methodMatcher);
|
|
158
|
+
break;
|
|
159
|
+
default:
|
|
160
|
+
throw new Error('Invalid respondWith invocation');
|
|
161
|
+
}
|
|
162
|
+
if (typeof urlMatcher.exec === 'function') {
|
|
163
|
+
urlMatcher = ((rx) => (url) => rx.exec(url)?.slice(1))(urlMatcher);
|
|
164
|
+
} else if (typeof urlMatcher === 'string') {
|
|
165
|
+
urlMatcher = ((toMatch) => (url) => url === toMatch)(urlMatcher);
|
|
166
|
+
}
|
|
167
|
+
responders.push((req) => {
|
|
168
|
+
if (req.readyState !== DONE && methodMatcher(req.method)) {
|
|
169
|
+
const arg = urlMatcher(req.url);
|
|
170
|
+
if (arg) {
|
|
171
|
+
if (typeof response === 'function') {
|
|
172
|
+
response(req, ...(Array.isArray(arg) ? arg : []));
|
|
173
|
+
} else if (typeof response === 'string') {
|
|
174
|
+
req.respond(200, null, response);
|
|
175
|
+
} else {
|
|
176
|
+
req.respond.apply(req, response);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function resetState() {
|
|
184
|
+
requests.length = 0;
|
|
185
|
+
responders.length = 0;
|
|
186
|
+
timeoutsEnabled = false;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
requests,
|
|
191
|
+
enable,
|
|
192
|
+
restore() {
|
|
193
|
+
resetState();
|
|
194
|
+
sandbox.restore();
|
|
195
|
+
enabled = false;
|
|
196
|
+
},
|
|
197
|
+
reset() {
|
|
198
|
+
sandbox.resetHistory();
|
|
199
|
+
resetState();
|
|
200
|
+
},
|
|
201
|
+
respondWith,
|
|
202
|
+
respond() {
|
|
203
|
+
if (arguments.length > 0) {
|
|
204
|
+
respondWith.apply(null, arguments);
|
|
205
|
+
}
|
|
206
|
+
requests.forEach(req => {
|
|
207
|
+
for (let i = responders.length - 1; i >= 0; i--) {
|
|
208
|
+
responders[i](req);
|
|
209
|
+
if (req.readyState === DONE) break;
|
|
210
|
+
}
|
|
211
|
+
if (req.readyState !== DONE) {
|
|
212
|
+
req.respond(404, {}, '');
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
},
|
|
216
|
+
/**
|
|
217
|
+
* the timeout mechanism is quite different between XHR and fetch
|
|
218
|
+
* by default, mocked fetch does not time out - to reflect fakeServer XHRs
|
|
219
|
+
* note that many tests will fire requests without caring or waiting for their response -
|
|
220
|
+
* if they are timed out later, during unrelated tests, the log messages might interfere with their
|
|
221
|
+
* assertions
|
|
222
|
+
*/
|
|
223
|
+
get autoTimeout() {
|
|
224
|
+
return timeoutsEnabled;
|
|
225
|
+
},
|
|
226
|
+
set autoTimeout(val) {
|
|
227
|
+
timeoutsEnabled = !!val;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
beforeEach(function () {
|
|
233
|
+
server.reset();
|
|
10
234
|
});
|
|
11
235
|
|
|
12
236
|
const bid = getUniqueIdentifierStr().substring(4);
|
|
@@ -20,12 +244,35 @@ afterEach(function () {
|
|
|
20
244
|
return (s) => s.split('\n').map(s => `${preamble} ${s}`).join('\n');
|
|
21
245
|
})();
|
|
22
246
|
|
|
247
|
+
function format(obj, body = null) {
|
|
248
|
+
if (obj == null) return obj;
|
|
249
|
+
const fmt = {};
|
|
250
|
+
let node = obj;
|
|
251
|
+
while (node != null) {
|
|
252
|
+
Object.keys(node).forEach((k) => {
|
|
253
|
+
const val = obj[k];
|
|
254
|
+
if (typeof val !== 'function' && !fmt.hasOwnProperty(k)) {
|
|
255
|
+
fmt[k] = val;
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
node = Object.getPrototypeOf(node);
|
|
259
|
+
}
|
|
260
|
+
if (obj.headers != null) {
|
|
261
|
+
fmt.headers = Object.fromEntries(obj.headers.entries())
|
|
262
|
+
}
|
|
263
|
+
fmt.body = body;
|
|
264
|
+
return fmt;
|
|
265
|
+
}
|
|
266
|
+
|
|
23
267
|
|
|
24
|
-
console.log(prepend(`XHR mock state after failure (for test '${this.currentTest.fullTitle()}'): ${server.requests.length} requests`))
|
|
268
|
+
console.log(prepend(`XHR mock state after failure (for test '${this.currentTest.fullTitle()}'): ${server.requests.length} requests`));
|
|
25
269
|
server.requests.forEach((req, i) => {
|
|
26
270
|
console.log(prepend(`Request #${i}:`));
|
|
27
|
-
console.log(prepend(JSON.stringify(
|
|
28
|
-
|
|
271
|
+
console.log(prepend(JSON.stringify({
|
|
272
|
+
request: format(req.fetch.request, req.fetch.requestBody),
|
|
273
|
+
response: format(req.fetch.response, req.fetch.responseBody)
|
|
274
|
+
}, null, 2)));
|
|
275
|
+
});
|
|
29
276
|
}
|
|
30
277
|
});
|
|
31
278
|
/* eslint-enable */
|