prebid.js 8.1.0 → 8.3.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/.devcontainer/devcontainer.json +3 -1
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admanBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adtelligentBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/beopBidAdapter.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/bridBidAdapter.js +1 -0
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/categoryTranslation.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/cmp.js +1 -0
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consentManagement.js +1 -1
- package/dist/consentManagementGpp.js +1 -1
- package/dist/consentManagementUsp.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/cwireBidAdapter.js +1 -1
- package/dist/dependencies.json +15 -0
- package/dist/discoveryBidAdapter.js +1 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/gppControl_usnat.js +1 -0
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/holidBidAdapter.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/intentIqIdSystem.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.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/liveIntentIdSystem.js +1 -1
- package/dist/livewrappedAnalyticsAdapter.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/mediagoBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/mspa.js +1 -0
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +144 -140
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.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 +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconBidAdapter.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/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/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/trafficgateBidAdapter.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/userId.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.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/libraries/cmp/cmpClient.js +139 -0
- package/libraries/mspa/activityControls.js +91 -0
- package/modules/adagioBidAdapter.js +2 -1
- package/modules/admanBidAdapter.js +5 -0
- package/modules/adtelligentBidAdapter.js +8 -0
- package/modules/beopBidAdapter.js +6 -6
- package/modules/beopBidAdapter.md +35 -1
- package/modules/bridBidAdapter.js +223 -0
- package/modules/cadentApertureMXBidAdapter.md +2 -2
- package/modules/categoryTranslation.js +3 -2
- package/modules/consentManagement.js +12 -86
- package/modules/consentManagementGpp.js +47 -126
- package/modules/consentManagementUsp.js +19 -97
- package/modules/discoveryBidAdapter.js +1 -1
- package/modules/gppControl_usnat.js +11 -0
- package/modules/holidBidAdapter.js +49 -30
- package/modules/intentIqIdSystem.js +6 -5
- package/modules/ixBidAdapter.js +2 -1
- package/modules/liveIntentIdSystem.js +8 -3
- package/modules/livewrappedAnalyticsAdapter.js +33 -33
- package/modules/mediagoBidAdapter.js +1 -0
- package/modules/mediasquareBidAdapter.js +19 -23
- package/modules/oxxionRtdProvider.js +124 -11
- package/modules/oxxionRtdProvider.md +19 -4
- package/modules/smartyadsBidAdapter.js +6 -3
- package/modules/sovrnBidAdapter.js +5 -0
- package/modules/trafficgateBidAdapter.js +126 -72
- package/modules/tripleliftBidAdapter.js +21 -1
- package/modules/userId/eids.js +29 -0
- package/modules/userId/eids.md +19 -2
- package/modules/userId/index.js +78 -29
- package/modules/userId/userId.md +3 -0
- package/modules/vidazooBidAdapter.js +68 -16
- package/package.json +1 -1
- package/src/activities/params.js +4 -1
- package/test/spec/libraries/cmp/cmpClient_spec.js +233 -0
- package/test/spec/libraries/mspa/activityControls_spec.js +315 -0
- package/test/spec/modules/adagioBidAdapter_spec.js +2 -1
- package/test/spec/modules/admanBidAdapter_spec.js +8 -2
- package/test/spec/modules/adqueryBidAdapter_spec.js +5 -1
- package/test/spec/modules/adtelligentBidAdapter_spec.js +8 -0
- package/test/spec/modules/beopBidAdapter_spec.js +18 -2
- package/test/spec/modules/bridBidAdapter_spec.js +129 -0
- package/test/spec/modules/byDataAnalyticsAdapter_spec.js +9 -7
- package/test/spec/modules/cadentApertureMXBidAdapter_spec.js +1 -1
- package/test/spec/modules/chtnwBidAdapter_spec.js +4 -1
- package/test/spec/modules/consentManagementGpp_spec.js +84 -7
- package/test/spec/modules/consentManagement_spec.js +8 -18
- package/test/spec/modules/datablocksBidAdapter_spec.js +7 -3
- package/test/spec/modules/eids_spec.js +87 -0
- package/test/spec/modules/holidBidAdapter_spec.js +26 -6
- package/test/spec/modules/insticatorBidAdapter_spec.js +6 -2
- package/test/spec/modules/intentIqIdSystem_spec.js +36 -2
- package/test/spec/modules/ixBidAdapter_spec.js +52 -18
- package/test/spec/modules/lassoBidAdapter_spec.js +6 -4
- package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +17 -2
- package/test/spec/modules/liveIntentIdSystem_spec.js +11 -6
- package/test/spec/modules/mediasquareBidAdapter_spec.js +3 -0
- package/test/spec/modules/onetagBidAdapter_spec.js +81 -75
- package/test/spec/modules/orbidderBidAdapter_spec.js +6 -3
- package/test/spec/modules/oxxionRtdProvider_spec.js +113 -1
- package/test/spec/modules/relaidoBidAdapter_spec.js +4 -3
- package/test/spec/modules/smartyadsBidAdapter_spec.js +1 -1
- package/test/spec/modules/sovrnBidAdapter_spec.js +34 -0
- package/test/spec/modules/trafficgateBidAdapter_spec.js +1349 -199
- package/test/spec/modules/tripleliftBidAdapter_spec.js +20 -1
- package/test/spec/modules/ucfunnelBidAdapter_spec.js +37 -16
- package/test/spec/modules/userId_spec.js +393 -6
- package/test/spec/modules/vidazooBidAdapter_spec.js +131 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {_each, deepAccess, parseSizesInput, parseUrl, uniques,
|
|
1
|
+
import {_each, chunk, deepAccess, isFn, parseSizesInput, parseUrl, uniques, isArray} from '../src/utils.js';
|
|
2
2
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
3
3
|
import {BANNER, VIDEO} from '../src/mediaTypes.js';
|
|
4
4
|
import {getStorageManager} from '../src/storageManager.js';
|
|
@@ -48,7 +48,7 @@ function isBidRequestValid(bid) {
|
|
|
48
48
|
return !!(extractCID(params) && extractPID(params));
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
function
|
|
51
|
+
function buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
|
|
52
52
|
const {
|
|
53
53
|
params,
|
|
54
54
|
bidId,
|
|
@@ -69,9 +69,7 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
|
|
|
69
69
|
const dealId = getNextDealId(hashUrl);
|
|
70
70
|
const uniqueDealId = getUniqueDealId(hashUrl);
|
|
71
71
|
const sId = getVidazooSessionId();
|
|
72
|
-
const cId = extractCID(params);
|
|
73
72
|
const pId = extractPID(params);
|
|
74
|
-
const subDomain = extractSubDomain(params);
|
|
75
73
|
const ptrace = getCacheOpt();
|
|
76
74
|
const isStorageAllowed = bidderSettings.get(BIDDER_CODE, 'storageAllowed');
|
|
77
75
|
|
|
@@ -153,17 +151,46 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
|
|
|
153
151
|
data.gppSid = bidderRequest.ortb2.regs.gpp_sid;
|
|
154
152
|
}
|
|
155
153
|
|
|
154
|
+
_each(ext, (value, key) => {
|
|
155
|
+
data['ext.' + key] = value;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return data;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) {
|
|
162
|
+
const {params} = bid;
|
|
163
|
+
const cId = extractCID(params);
|
|
164
|
+
const subDomain = extractSubDomain(params);
|
|
165
|
+
const data = buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout);
|
|
156
166
|
const dto = {
|
|
157
167
|
method: 'POST',
|
|
158
168
|
url: `${createDomain(subDomain)}/prebid/multi/${cId}`,
|
|
159
169
|
data: data
|
|
160
170
|
};
|
|
171
|
+
return dto;
|
|
172
|
+
}
|
|
161
173
|
|
|
162
|
-
|
|
163
|
-
|
|
174
|
+
function buildSingleRequest(bidRequests, bidderRequest, topWindowUrl, bidderTimeout) {
|
|
175
|
+
const {params} = bidRequests[0];
|
|
176
|
+
const cId = extractCID(params);
|
|
177
|
+
const subDomain = extractSubDomain(params);
|
|
178
|
+
const data = bidRequests.map(bid => {
|
|
179
|
+
const sizes = parseSizesInput(bid.sizes);
|
|
180
|
+
return buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout)
|
|
181
|
+
});
|
|
182
|
+
const CHUNK_SIZE = Math.min(10, config.getConfig('vidazoo.chunkSize') || 10);
|
|
183
|
+
|
|
184
|
+
const chunkedData = chunk(data, CHUNK_SIZE);
|
|
185
|
+
return chunkedData.map(chunk => {
|
|
186
|
+
return {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
url: `${createDomain(subDomain)}/prebid/multi/${cId}`,
|
|
189
|
+
data: {
|
|
190
|
+
bids: chunk
|
|
191
|
+
}
|
|
192
|
+
};
|
|
164
193
|
});
|
|
165
|
-
|
|
166
|
-
return dto;
|
|
167
194
|
}
|
|
168
195
|
|
|
169
196
|
function appendUserIdsToRequestPayload(payloadRef, userIds) {
|
|
@@ -193,12 +220,33 @@ function buildRequests(validBidRequests, bidderRequest) {
|
|
|
193
220
|
// TODO: does the fallback make sense here?
|
|
194
221
|
const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation;
|
|
195
222
|
const bidderTimeout = config.getConfig('bidderTimeout');
|
|
223
|
+
|
|
224
|
+
const singleRequestMode = config.getConfig('vidazoo.singleRequest');
|
|
225
|
+
|
|
196
226
|
const requests = [];
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
227
|
+
|
|
228
|
+
if (singleRequestMode) {
|
|
229
|
+
// We need to split the requests into banner and video requests
|
|
230
|
+
const bannerBidRequests = validBidRequests.filter(bid => isArray(bid.mediaTypes) ? bid.mediaTypes.includes(BANNER) : bid.mediaTypes[BANNER] !== undefined);
|
|
231
|
+
if (bannerBidRequests.length > 0) {
|
|
232
|
+
const singleRequests = buildSingleRequest(bannerBidRequests, bidderRequest, topWindowUrl, bidderTimeout);
|
|
233
|
+
requests.push(...singleRequests);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Video Logic
|
|
237
|
+
const videoBidRequests = validBidRequests.filter(bid => bid.mediaTypes[VIDEO] !== undefined);
|
|
238
|
+
videoBidRequests.forEach(validBidRequest => {
|
|
239
|
+
const sizes = parseSizesInput(validBidRequest.sizes);
|
|
240
|
+
const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout);
|
|
241
|
+
requests.push(request);
|
|
242
|
+
});
|
|
243
|
+
} else {
|
|
244
|
+
validBidRequests.forEach(validBidRequest => {
|
|
245
|
+
const sizes = parseSizesInput(validBidRequest.sizes);
|
|
246
|
+
const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest, bidderTimeout);
|
|
247
|
+
requests.push(request);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
202
250
|
return requests;
|
|
203
251
|
}
|
|
204
252
|
|
|
@@ -206,13 +254,15 @@ function interpretResponse(serverResponse, request) {
|
|
|
206
254
|
if (!serverResponse || !serverResponse.body) {
|
|
207
255
|
return [];
|
|
208
256
|
}
|
|
209
|
-
|
|
257
|
+
|
|
258
|
+
const singleRequestMode = config.getConfig('vidazoo.singleRequest');
|
|
259
|
+
const reqBidId = deepAccess(request, 'data.bidId');
|
|
210
260
|
const {results} = serverResponse.body;
|
|
211
261
|
|
|
212
262
|
let output = [];
|
|
213
263
|
|
|
214
264
|
try {
|
|
215
|
-
results.forEach(result => {
|
|
265
|
+
results.forEach((result, i) => {
|
|
216
266
|
const {
|
|
217
267
|
creativeId,
|
|
218
268
|
ad,
|
|
@@ -221,6 +271,7 @@ function interpretResponse(serverResponse, request) {
|
|
|
221
271
|
width,
|
|
222
272
|
height,
|
|
223
273
|
currency,
|
|
274
|
+
bidId,
|
|
224
275
|
advertiserDomains,
|
|
225
276
|
metaData,
|
|
226
277
|
mediaType = BANNER
|
|
@@ -230,7 +281,7 @@ function interpretResponse(serverResponse, request) {
|
|
|
230
281
|
}
|
|
231
282
|
|
|
232
283
|
const response = {
|
|
233
|
-
requestId: bidId,
|
|
284
|
+
requestId: (singleRequestMode && bidId) ? bidId : reqBidId,
|
|
234
285
|
cpm: price,
|
|
235
286
|
width: width,
|
|
236
287
|
height: height,
|
|
@@ -264,6 +315,7 @@ function interpretResponse(serverResponse, request) {
|
|
|
264
315
|
}
|
|
265
316
|
output.push(response);
|
|
266
317
|
});
|
|
318
|
+
|
|
267
319
|
return output;
|
|
268
320
|
} catch (e) {
|
|
269
321
|
return [];
|
package/package.json
CHANGED
package/src/activities/params.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {MODULE_TYPE_BIDDER} from './modules.js';
|
|
2
|
+
import {hook} from '../hook.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Component ID - who is trying to perform the activity?
|
|
@@ -54,6 +55,8 @@ export function activityParamsBuilder(resolveAlias) {
|
|
|
54
55
|
if (moduleType === MODULE_TYPE_BIDDER) {
|
|
55
56
|
defaults[ACTIVITY_PARAM_ADAPTER_CODE] = resolveAlias(moduleName);
|
|
56
57
|
}
|
|
57
|
-
return Object.assign(defaults, params);
|
|
58
|
+
return buildActivityParams(Object.assign(defaults, params));
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
|
|
62
|
+
export const buildActivityParams = hook('sync', params => params);
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import {cmpClient} from '../../../../libraries/cmp/cmpClient.js';
|
|
2
|
+
|
|
3
|
+
describe('cmpClient', () => {
|
|
4
|
+
function mockWindow(props = {}) {
|
|
5
|
+
let listeners = [];
|
|
6
|
+
const win = {
|
|
7
|
+
addEventListener: sinon.stub().callsFake((evt, listener) => {
|
|
8
|
+
evt === 'message' && listeners.push(listener)
|
|
9
|
+
}),
|
|
10
|
+
postMessage: sinon.stub().callsFake((msg) => {
|
|
11
|
+
listeners.forEach(ln => ln({data: msg}))
|
|
12
|
+
}),
|
|
13
|
+
...props,
|
|
14
|
+
};
|
|
15
|
+
win.top = win.parent?.top || win;
|
|
16
|
+
return win;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
it('should return undefined when there is no CMP', () => {
|
|
20
|
+
expect(cmpClient({apiName: 'missing'}, mockWindow())).to.not.exist;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should return undefined when parent is inaccessible', () => {
|
|
24
|
+
const win = mockWindow();
|
|
25
|
+
win.top = mockWindow();
|
|
26
|
+
expect(cmpClient({apiName: 'missing'}, win)).to.not.exist;
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe('direct access', () => {
|
|
30
|
+
let mockApiFn;
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
mockApiFn = sinon.stub();
|
|
33
|
+
})
|
|
34
|
+
Object.entries({
|
|
35
|
+
'on same frame': () => mockWindow({mockApiFn}),
|
|
36
|
+
'on parent frame': () => mockWindow({parent: mockWindow({parent: mockWindow({parent: mockWindow(), mockApiFn})})}),
|
|
37
|
+
}).forEach(([t, mkWindow]) => {
|
|
38
|
+
describe(t, () => {
|
|
39
|
+
let win, mkClient;
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
win = mkWindow();
|
|
42
|
+
mkClient = (opts) => cmpClient(Object.assign({apiName: 'mockApiFn'}, opts), win)
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should mark client function as direct', () => {
|
|
46
|
+
expect(mkClient().isDirect).to.equal(true);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should find and call the CMP api function', () => {
|
|
50
|
+
mkClient()({command: 'mockCmd'});
|
|
51
|
+
sinon.assert.calledWith(mockApiFn, 'mockCmd');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('should return a promise that', () => {
|
|
55
|
+
let cbResult;
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
cbResult = [];
|
|
58
|
+
mockApiFn.callsFake((cmd, callback) => {
|
|
59
|
+
if (typeof callback === 'function') {
|
|
60
|
+
callback.apply(this, cbResult);
|
|
61
|
+
}
|
|
62
|
+
return 'val'
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
Object.entries({
|
|
66
|
+
callback: [sinon.stub(), 'undefined', undefined],
|
|
67
|
+
'no callback': [undefined, 'api return value', 'val']
|
|
68
|
+
}).forEach(([t, [callback, tResult, expectedResult]]) => {
|
|
69
|
+
describe(`when ${t} is provided`, () => {
|
|
70
|
+
Object.entries({
|
|
71
|
+
'no success flag': undefined,
|
|
72
|
+
'success is set': true
|
|
73
|
+
}).forEach(([t, success]) => {
|
|
74
|
+
it(`resolves to ${tResult} (${t})`, (done) => {
|
|
75
|
+
cbResult = ['cbVal', success];
|
|
76
|
+
mkClient()({callback}).then((val) => {
|
|
77
|
+
expect(val).to.equal(expectedResult);
|
|
78
|
+
done();
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('rejects to undefined when callback is provided and success = false', () => {
|
|
86
|
+
cbResult = ['cbVal', false];
|
|
87
|
+
mkClient()({callback: sinon.stub()}).catch(val => {
|
|
88
|
+
expect(val).to.equal('cbVal');
|
|
89
|
+
done();
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('rejects when CMP api throws', (done) => {
|
|
94
|
+
mockApiFn.reset();
|
|
95
|
+
const e = new Error();
|
|
96
|
+
mockApiFn.throws(e);
|
|
97
|
+
mkClient()({}).catch(val => {
|
|
98
|
+
expect(val).to.equal(e);
|
|
99
|
+
done();
|
|
100
|
+
});
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('should use apiArgs to choose and order the arguments to pass to the API fn', () => {
|
|
105
|
+
mkClient({apiArgs: ['parameter', 'command']})({
|
|
106
|
+
command: 'mockCmd',
|
|
107
|
+
parameter: 'mockParam',
|
|
108
|
+
callback() {}
|
|
109
|
+
});
|
|
110
|
+
sinon.assert.calledWith(mockApiFn, 'mockParam', 'mockCmd');
|
|
111
|
+
});
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('postMessage access', () => {
|
|
117
|
+
let messenger, win, response;
|
|
118
|
+
beforeEach(() => {
|
|
119
|
+
response = {};
|
|
120
|
+
messenger = sinon.stub().callsFake((msg) => {
|
|
121
|
+
if (msg.mockApiCall) {
|
|
122
|
+
win.postMessage({mockApiReturn: {callId: msg.mockApiCall.callId, ...response}});
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
function mkClient(options) {
|
|
128
|
+
return cmpClient(Object.assign({apiName: 'mockApi'}, options), win);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
Object.entries({
|
|
132
|
+
'on same frame': () => {
|
|
133
|
+
win = mockWindow({frames: {mockApiLocator: true}});
|
|
134
|
+
win.addEventListener('message', (evt) => messenger(evt.data));
|
|
135
|
+
},
|
|
136
|
+
'on parent frame': () => {
|
|
137
|
+
win = mockWindow({parent: mockWindow({frames: {mockApiLocator: true}})})
|
|
138
|
+
win.parent.addEventListener('message', evt => messenger(evt.data))
|
|
139
|
+
}
|
|
140
|
+
}).forEach(([t, setup]) => {
|
|
141
|
+
describe(t, () => {
|
|
142
|
+
beforeEach(setup);
|
|
143
|
+
|
|
144
|
+
it('should mark client as not direct', () => {
|
|
145
|
+
expect(mkClient().isDirect).to.equal(false);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should find and message the CMP frame', () => {
|
|
149
|
+
mkClient()({command: 'mockCmd', parameter: 'param'});
|
|
150
|
+
sinon.assert.calledWithMatch(messenger, {
|
|
151
|
+
mockApiCall: {
|
|
152
|
+
command: 'mockCmd',
|
|
153
|
+
parameter: 'param'
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should use apiArgs to choose what to include in the message payload', () => {
|
|
159
|
+
mkClient({apiArgs: ['command']})({
|
|
160
|
+
command: 'cmd',
|
|
161
|
+
parameter: 'param'
|
|
162
|
+
});
|
|
163
|
+
sinon.assert.calledWithMatch(messenger, sinon.match((arg) => {
|
|
164
|
+
return arg.mockApiCall.command === 'cmd' &&
|
|
165
|
+
!arg.mockApiCall.hasOwnProperty('parameter');
|
|
166
|
+
}))
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should not include callback in the payload, but still run it on response', () => {
|
|
170
|
+
const cb = sinon.stub();
|
|
171
|
+
mkClient({apiArgs: ['command', 'callback']})({
|
|
172
|
+
command: 'cmd',
|
|
173
|
+
callback: cb
|
|
174
|
+
});
|
|
175
|
+
sinon.assert.calledWithMatch(messenger, sinon.match(arg => !arg.mockApiCall.hasOwnProperty('callback')));
|
|
176
|
+
sinon.assert.called(cb);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should use callbackArgs to decide what to pass to callback', () => {
|
|
180
|
+
const cb = sinon.stub();
|
|
181
|
+
response = {a: 'one', b: 'two'};
|
|
182
|
+
mkClient({callbackArgs: ['a', 'b']})({callback: cb});
|
|
183
|
+
sinon.assert.calledWith(cb, 'one', 'two');
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
describe('should return a promise that', () => {
|
|
187
|
+
beforeEach(() => {
|
|
188
|
+
response = {returnValue: 'val'}
|
|
189
|
+
})
|
|
190
|
+
Object.entries({
|
|
191
|
+
'callback': [sinon.stub(), 'undefined', undefined],
|
|
192
|
+
'no callback': [undefined, 'response returnValue', 'val'],
|
|
193
|
+
}).forEach(([t, [callback, tResult, expectedResult]]) => {
|
|
194
|
+
describe(`when ${t} is provided`, () => {
|
|
195
|
+
Object.entries({
|
|
196
|
+
'no success flag': {},
|
|
197
|
+
'with success flag': {success: true}
|
|
198
|
+
}).forEach(([t, resp]) => {
|
|
199
|
+
it(`resolves to ${tResult} (${t})`, () => {
|
|
200
|
+
Object.assign(response, resp);
|
|
201
|
+
mkClient()({callback}).then((val) => {
|
|
202
|
+
expect(val).to.equal(expectedResult);
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it(`rejects to ${tResult} when success = false`, (done) => {
|
|
208
|
+
response.success = false;
|
|
209
|
+
mkClient()({callback}).catch((err) => {
|
|
210
|
+
expect(err).to.equal(expectedResult);
|
|
211
|
+
done();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
})
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should re-use callback for messages with same callId', () => {
|
|
219
|
+
messenger.reset();
|
|
220
|
+
let callId;
|
|
221
|
+
messenger.callsFake((msg) => { if (msg.mockApiCall) callId = msg.mockApiCall.callId });
|
|
222
|
+
const callback = sinon.stub();
|
|
223
|
+
mkClient()({callback});
|
|
224
|
+
expect(callId).to.exist;
|
|
225
|
+
win.postMessage({mockApiReturn: {callId, returnValue: 'a'}});
|
|
226
|
+
win.postMessage({mockApiReturn: {callId, returnValue: 'b'}});
|
|
227
|
+
sinon.assert.calledWith(callback, 'a');
|
|
228
|
+
sinon.assert.calledWith(callback, 'b');
|
|
229
|
+
})
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|