prebid-universal-creative 1.14.2 → 1.16.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/.babelrc +1 -2
- package/.github/workflows/issue_tracker.yml +31 -16
- package/README.md +21 -3
- package/dist/amp.js +3 -0
- package/dist/banner.js +3 -0
- package/dist/creative.js +4 -3
- package/dist/creative.max.js +546 -593
- package/dist/load-cookie-with-consent.html +1 -1
- package/dist/load-cookie.html +1 -1
- package/dist/mobile.js +3 -0
- package/dist/native-render.js +3 -3
- package/dist/native-trk.js +3 -3
- package/dist/native.js +3 -0
- package/dist/uid.js +3 -3
- package/dist/video.js +3 -0
- package/gulpfile.js +84 -45
- package/karma.conf.maker.js +4 -6
- package/package.json +80 -82
- package/src/ampOrMobile.js +14 -0
- package/src/creative.js +2 -9
- package/src/environment.js +62 -75
- package/src/legacy.js +29 -0
- package/src/legacyNativeRender.js +6 -0
- package/src/mobileAndAmpRender.js +239 -0
- package/src/nativeAssetManager.js +91 -57
- package/src/nativeORTBTrackerManager.js +2 -2
- package/src/nativeRender.js +2 -2
- package/src/nativeRenderManager.js +46 -69
- package/src/postscribeRender.js +10 -0
- package/src/renderingManager.js +106 -358
- package/src/utils.js +1 -11
- package/template/amp/dfp-creative.html +1 -1
- package/test/spec/environment_spec.js +4 -11
- package/test/spec/legacyNativeRender_spec.js +25 -0
- package/test/spec/mobileAndAmpRender_spec.js +316 -0
- package/test/spec/nativeAssetManager_spec.js +227 -79
- package/test/spec/nativeORTBTrackerManager_spec.js +3 -19
- package/test/spec/nativeRenderManager_spec.js +77 -55
- package/test/spec/nativeRender_spec.js +23 -0
- package/test/spec/renderingManager_spec.js +16 -265
- package/webpack.conf.js +3 -1
@@ -1,8 +1,9 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
1
|
+
import {expect} from 'chai';
|
2
|
+
import {merge} from 'lodash';
|
3
|
+
import {newNativeAssetManager} from 'src/nativeAssetManager';
|
4
|
+
import {mocks} from 'test/helpers/mocks';
|
5
5
|
import * as utils from 'src/utils';
|
6
|
+
import {prebidMessenger} from '../../src/messaging.js';
|
6
7
|
|
7
8
|
const ORIGIN = 'https://origin.com'
|
8
9
|
const AD_ID = 'abc123';
|
@@ -12,6 +13,7 @@ const NATIVE_KEYS = {
|
|
12
13
|
body: 'hb_native_body',
|
13
14
|
body2: 'hb_native_body2',
|
14
15
|
privacyLink: 'hb_native_privacy',
|
16
|
+
privacyIcon: 'hb_native_privicon',
|
15
17
|
sponsoredBy: 'hb_native_brand',
|
16
18
|
image: 'hb_native_image',
|
17
19
|
icon: 'hb_native_icon',
|
@@ -39,11 +41,16 @@ const mockDocument = {
|
|
39
41
|
};
|
40
42
|
|
41
43
|
// creates mock postmessage response from prebid's native.js:getAssetMessage
|
42
|
-
function createResponder(assets,url,template) {
|
44
|
+
function createResponder(assets,url,template, clickUrlUnesc = '') {
|
43
45
|
return function(type, listener) {
|
44
46
|
if (type !== 'message') { return; }
|
45
47
|
|
46
|
-
const data = {
|
48
|
+
const data = {
|
49
|
+
message: 'assetResponse',
|
50
|
+
adId: AD_ID, assets,
|
51
|
+
adTemplate:template,
|
52
|
+
rendererUrl:url,
|
53
|
+
};
|
47
54
|
listener({ data: JSON.stringify(data), origin: ORIGIN});
|
48
55
|
};
|
49
56
|
}
|
@@ -85,8 +92,11 @@ function generateRenderer(assets) {
|
|
85
92
|
describe('nativeAssetManager', () => {
|
86
93
|
let win;
|
87
94
|
|
88
|
-
function makeManager() {
|
89
|
-
return newNativeAssetManager(win,
|
95
|
+
function makeManager(args, mkMessenger = prebidMessenger) {
|
96
|
+
return newNativeAssetManager(win, {
|
97
|
+
pubUrl: ORIGIN,
|
98
|
+
...args
|
99
|
+
}, mkMessenger);
|
90
100
|
}
|
91
101
|
|
92
102
|
beforeEach(() => {
|
@@ -111,10 +121,10 @@ describe('nativeAssetManager', () => {
|
|
111
121
|
{ key: 'body', value: 'new value' },
|
112
122
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
113
123
|
]);
|
114
|
-
|
124
|
+
|
115
125
|
const nativeAssetManager = makeManager();
|
116
126
|
nativeAssetManager.loadAssets(AD_ID);
|
117
|
-
|
127
|
+
|
118
128
|
expect(win.document.body.innerHTML).to.include('<p>new value</p>');
|
119
129
|
expect(win.document.body.innerHTML).to.include(`
|
120
130
|
<a href="http://www.example.com">Click Here</a>
|
@@ -122,17 +132,17 @@ describe('nativeAssetManager', () => {
|
|
122
132
|
// title was not a requested asset so this should stay as is
|
123
133
|
expect(win.document.body.innerHTML).to.include('<h1>hb_native_title</h1>');
|
124
134
|
});
|
125
|
-
|
135
|
+
|
126
136
|
it('replaces all occurrences of the placeholder if it appears more than once', () => {
|
127
137
|
win.document.body.innerHTML = `
|
128
138
|
<a href="hb_native_linkurl:${AD_ID}">Click Here</a>
|
129
139
|
<a href="hb_native_linkurl:${AD_ID}">Or Here</a>
|
130
140
|
`;
|
131
141
|
win.addEventListener = createResponder([{ key: 'clickUrl', value: 'http://www.example.com' }]);
|
132
|
-
|
142
|
+
|
133
143
|
const nativeAssetManager = makeManager();
|
134
144
|
nativeAssetManager.loadAssets(AD_ID);
|
135
|
-
|
145
|
+
|
136
146
|
expect(win.document.body.innerHTML).to.include(`
|
137
147
|
<a href="http://www.example.com">Click Here</a>
|
138
148
|
`);
|
@@ -140,23 +150,22 @@ describe('nativeAssetManager', () => {
|
|
140
150
|
<a href="http://www.example.com">Or Here</a>
|
141
151
|
`);
|
142
152
|
});
|
143
|
-
|
153
|
+
|
144
154
|
it('attaches and removes message listeners', (done) => {
|
145
155
|
win.document.body.innerHTML = `<h1>hb_native_title:${AD_ID}</h1>`;
|
146
156
|
const responder = createResponder();
|
147
157
|
win.addEventListener = function (evType, listener) {
|
148
158
|
setTimeout(() => responder(evType, listener), 0);
|
149
159
|
}
|
150
|
-
|
160
|
+
|
151
161
|
const nativeAssetManager = makeManager();
|
152
162
|
nativeAssetManager.loadAssets(AD_ID);
|
153
163
|
setTimeout(() => {
|
154
|
-
expect(win.parent.postMessage.callCount).to.equal(1);
|
155
164
|
expect(win.removeEventListener.callCount).to.equal(1);
|
156
165
|
done();
|
157
166
|
}, 0);
|
158
167
|
});
|
159
|
-
|
168
|
+
|
160
169
|
it('replaces native placeholders with their asset values from adTemplate', () => {
|
161
170
|
const html = `<script>
|
162
171
|
let nativeTag = {};
|
@@ -171,7 +180,7 @@ describe('nativeAssetManager', () => {
|
|
171
180
|
adId : AD_ID,
|
172
181
|
adTemplate : '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'
|
173
182
|
};
|
174
|
-
|
183
|
+
|
175
184
|
win.document.body.innerHTML = html;
|
176
185
|
win.addEventListener = createResponder([
|
177
186
|
{ key: 'body', value: 'Body content' },
|
@@ -179,15 +188,15 @@ describe('nativeAssetManager', () => {
|
|
179
188
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
180
189
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
181
190
|
]);
|
182
|
-
|
191
|
+
|
183
192
|
const nativeAssetManager = makeManager();
|
184
193
|
nativeAssetManager.loadAssets(AD_ID);
|
185
|
-
|
194
|
+
|
186
195
|
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
187
196
|
expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
|
188
197
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
189
198
|
});
|
190
|
-
|
199
|
+
|
191
200
|
it('loads rendererUrl and passes assets to renderAd - writes response to innerHtml', () => {
|
192
201
|
const html = `<script>
|
193
202
|
let nativeTag = {};
|
@@ -202,25 +211,25 @@ describe('nativeAssetManager', () => {
|
|
202
211
|
rendererUrl : 'https://www.renderer.com/render.js',
|
203
212
|
requestAllAssets : true
|
204
213
|
};
|
205
|
-
|
214
|
+
|
206
215
|
win.document.body.innerHTML = html;
|
207
216
|
win.renderAd = generateRenderer;
|
208
|
-
|
217
|
+
|
209
218
|
win.addEventListener = createAllResponder([
|
210
219
|
{ key: 'body', value: 'Body content' },
|
211
220
|
{ key: 'title', value: 'new value' },
|
212
221
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
213
222
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
214
223
|
],null,null);
|
215
|
-
|
224
|
+
|
216
225
|
const nativeAssetManager = makeManager();
|
217
226
|
nativeAssetManager.loadAssets(AD_ID);
|
218
|
-
|
227
|
+
|
219
228
|
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
220
229
|
expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
|
221
230
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
222
231
|
});
|
223
|
-
|
232
|
+
|
224
233
|
it('adId does not match, so assets are not replaced', () => {
|
225
234
|
const html = `<script>
|
226
235
|
let nativeTag = {};
|
@@ -235,20 +244,20 @@ describe('nativeAssetManager', () => {
|
|
235
244
|
rendererUrl : 'https://www.renderer.com/render.js',
|
236
245
|
requestAllAssets : true
|
237
246
|
};
|
238
|
-
|
247
|
+
|
239
248
|
win.document.body.innerHTML = html;
|
240
249
|
win.renderAd = generateRenderer;
|
241
|
-
|
250
|
+
|
242
251
|
win.addEventListener = createAllResponder([
|
243
252
|
{ key: 'body', value: 'Body content' },
|
244
253
|
{ key: 'title', value: 'new value' },
|
245
254
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
246
255
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
247
256
|
],null,null);
|
248
|
-
|
257
|
+
|
249
258
|
const nativeAssetManager = makeManager();
|
250
259
|
nativeAssetManager.loadAssets(AD_ID);
|
251
|
-
|
260
|
+
|
252
261
|
expect(win.document.body.innerHTML).to.equal(`<script>
|
253
262
|
let nativeTag = {};
|
254
263
|
nativeTag.pubUrl = "https://www.url.com";
|
@@ -257,7 +266,7 @@ describe('nativeAssetManager', () => {
|
|
257
266
|
window.pbNativeTag.renderNativeAd(nativeTag);
|
258
267
|
</script>`);
|
259
268
|
});
|
260
|
-
|
269
|
+
|
261
270
|
it('adId does not match on first response, so assets are not replaced until match on second response', () => {
|
262
271
|
const html = `<script>
|
263
272
|
let nativeTag = {};
|
@@ -272,20 +281,20 @@ describe('nativeAssetManager', () => {
|
|
272
281
|
rendererUrl : 'https://www.renderer.com/render.js',
|
273
282
|
requestAllAssets : true
|
274
283
|
};
|
275
|
-
|
284
|
+
|
276
285
|
win.document.body.innerHTML = html;
|
277
286
|
win.renderAd = generateRenderer;
|
278
|
-
|
287
|
+
|
279
288
|
win.addEventListener = createAllResponder([
|
280
289
|
{ key: 'body', value: 'Body No Replace' },
|
281
290
|
{ key: 'title', value: 'new value no replace' },
|
282
291
|
{ key: 'clickUrl', value: 'http://www.example.com/noreplace' },
|
283
292
|
{ key: 'image', value: 'http://www.image.com/picture.jpg?noreplace=true' },
|
284
293
|
],null,null);
|
285
|
-
|
294
|
+
|
286
295
|
const nativeAssetManager = makeManager();
|
287
296
|
nativeAssetManager.loadAssets(AD_ID2);
|
288
|
-
|
297
|
+
|
289
298
|
expect(win.document.body.innerHTML).to.equal(`<script>
|
290
299
|
let nativeTag = {};
|
291
300
|
nativeTag.pubUrl = "https://www.url.com";
|
@@ -293,21 +302,21 @@ describe('nativeAssetManager', () => {
|
|
293
302
|
nativeTag.requestAllAssets = true;
|
294
303
|
window.pbNativeTag.renderNativeAd(nativeTag);
|
295
304
|
</script>`);
|
296
|
-
|
305
|
+
|
297
306
|
win.addEventListener = createAltAllResponder([
|
298
307
|
{ key: 'body', value: 'Body content' },
|
299
308
|
{ key: 'title', value: 'new value' },
|
300
309
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
301
310
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
302
311
|
],null,null);
|
303
|
-
|
312
|
+
|
304
313
|
nativeAssetManager.loadAssets(AD_ID2);
|
305
|
-
|
314
|
+
|
306
315
|
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
307
316
|
expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
|
308
317
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
309
318
|
});
|
310
|
-
|
319
|
+
|
311
320
|
it('no placeholders found but requests all assets flag set - rendererUrl', () => {
|
312
321
|
const url = 'https://www.renderer.com/render.js';
|
313
322
|
win.pbNativeData = {
|
@@ -316,25 +325,25 @@ describe('nativeAssetManager', () => {
|
|
316
325
|
rendererUrl : 'https://www.renderer.com/render.js',
|
317
326
|
requestAllAssets : true
|
318
327
|
};
|
319
|
-
|
328
|
+
|
320
329
|
win.document.body.innerHTML = '';
|
321
330
|
win.renderAd = generateRenderer;
|
322
|
-
|
331
|
+
|
323
332
|
win.addEventListener = createAllResponder([
|
324
333
|
{ key: 'body', value: 'Body content' },
|
325
334
|
{ key: 'title', value: 'new value' },
|
326
335
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
327
336
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
328
337
|
],url,null);
|
329
|
-
|
338
|
+
|
330
339
|
const nativeAssetManager = makeManager();
|
331
340
|
nativeAssetManager.loadAssets(AD_ID);
|
332
|
-
|
341
|
+
|
333
342
|
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
334
343
|
expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
|
335
344
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
336
345
|
});
|
337
|
-
|
346
|
+
|
338
347
|
it("no placeholders found but requests all assets flag set - adTemplate - openRTB", () => {
|
339
348
|
const template = `
|
340
349
|
<div class="sponsored-post">
|
@@ -348,6 +357,7 @@ describe('nativeAssetManager', () => {
|
|
348
357
|
<div class="attribution">
|
349
358
|
<img class="pb-icon" src="##hb_native_asset_id_3##" alt="icon" height="150" width="50">
|
350
359
|
</div>
|
360
|
+
<h2>##hb_native_asset_id_1##</h2>
|
351
361
|
<p>##hb_native_asset_id_4##</p>
|
352
362
|
</div>
|
353
363
|
</div>
|
@@ -357,9 +367,9 @@ describe('nativeAssetManager', () => {
|
|
357
367
|
adId: AD_ID,
|
358
368
|
requestAllAssets: true,
|
359
369
|
};
|
360
|
-
|
370
|
+
|
361
371
|
win.document.body.innerHTML = "";
|
362
|
-
|
372
|
+
|
363
373
|
win.addEventListener = createAllResponder(
|
364
374
|
{
|
365
375
|
assets: [
|
@@ -391,10 +401,10 @@ describe('nativeAssetManager', () => {
|
|
391
401
|
template,
|
392
402
|
"ortb"
|
393
403
|
);
|
394
|
-
|
404
|
+
|
395
405
|
const nativeAssetManager = makeManager();
|
396
406
|
nativeAssetManager.loadAssets(AD_ID);
|
397
|
-
|
407
|
+
|
398
408
|
expect(win.document.body.innerHTML).to.include(
|
399
409
|
`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`
|
400
410
|
);
|
@@ -403,11 +413,14 @@ describe('nativeAssetManager', () => {
|
|
403
413
|
);
|
404
414
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
405
415
|
|
406
|
-
// ##hb_native_asset_id_4## was not returned in the response, it should
|
416
|
+
// ##hb_native_asset_id_4## was not returned in the response, it should
|
407
417
|
// be transformed into an empty string
|
408
418
|
expect(win.document.body.innerHTML).to.not.include(`##hb_native_asset_id_4##`);
|
419
|
+
|
420
|
+
// test that we are replacing ALL asset occurrences
|
421
|
+
expect(([...win.document.body.innerHTML.match(/new value/g)] || []).length, "expected 2 occurrences of \"new value\"").to.equal(2);
|
409
422
|
});
|
410
|
-
|
423
|
+
|
411
424
|
it('no placeholders found but requests all assets flag set - adTemplate', () => {
|
412
425
|
const template = '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>';
|
413
426
|
win.pbNativeData = {
|
@@ -415,24 +428,24 @@ describe('nativeAssetManager', () => {
|
|
415
428
|
adId : AD_ID,
|
416
429
|
requestAllAssets : true
|
417
430
|
};
|
418
|
-
|
431
|
+
|
419
432
|
win.document.body.innerHTML = '';
|
420
|
-
|
433
|
+
|
421
434
|
win.addEventListener = createAllResponder([
|
422
435
|
{ key: 'body', value: 'Body content' },
|
423
436
|
{ key: 'title', value: 'new value' },
|
424
437
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
425
438
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
426
439
|
],null,template);
|
427
|
-
|
440
|
+
|
428
441
|
const nativeAssetManager = makeManager();
|
429
442
|
nativeAssetManager.loadAssets(AD_ID);
|
430
|
-
|
443
|
+
|
431
444
|
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
432
445
|
expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
|
433
446
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
434
447
|
});
|
435
|
-
|
448
|
+
|
436
449
|
it('no placeholders found but assets defined in nativeTag - adTemplate', () => {
|
437
450
|
const template = '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>';
|
438
451
|
win.pbNativeData = {
|
@@ -440,54 +453,54 @@ describe('nativeAssetManager', () => {
|
|
440
453
|
adId : AD_ID,
|
441
454
|
assetsToReplace: ['image','hb_native_body','clickUrl','hb_native_title']
|
442
455
|
};
|
443
|
-
|
456
|
+
|
444
457
|
win.document.body.innerHTML = '';
|
445
|
-
|
458
|
+
|
446
459
|
win.addEventListener = createAllResponder([
|
447
460
|
{ key: 'body', value: 'Body content' },
|
448
461
|
{ key: 'title', value: 'new value' },
|
449
462
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
450
463
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
451
464
|
],null,template);
|
452
|
-
|
465
|
+
|
453
466
|
const nativeAssetManager = makeManager();
|
454
467
|
nativeAssetManager.loadAssets(AD_ID);
|
455
|
-
|
468
|
+
|
456
469
|
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
457
470
|
expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
|
458
471
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
459
472
|
});
|
460
|
-
|
473
|
+
|
461
474
|
it('does not replace anything if no placeholders found', () => {
|
462
475
|
const html = `
|
463
476
|
<h1>Native Ad</h1>
|
464
477
|
<p>Cool Description</p>
|
465
478
|
<a href="http://www.example.com">Click</a>
|
466
479
|
`;
|
467
|
-
|
480
|
+
|
468
481
|
win.document.body.innerHTML = html;
|
469
482
|
win.addEventListener = createResponder();
|
470
|
-
|
483
|
+
|
471
484
|
const nativeAssetManager = makeManager();
|
472
485
|
nativeAssetManager.loadAssets(AD_ID);
|
473
|
-
|
486
|
+
|
474
487
|
expect(win.document.body.innerHTML).to.equal(html);
|
475
488
|
});
|
476
|
-
|
489
|
+
|
477
490
|
it('replace mobile native placeholder with their values', function() {
|
478
491
|
win.document.body.innerHTML = `
|
479
492
|
<h1>hb_native_cta</h1>
|
480
493
|
<p>hb_native_body</p>
|
481
494
|
<a href="hb_native_linkurl">Click Here</a>
|
482
495
|
`;
|
483
|
-
|
496
|
+
|
484
497
|
let cb = sinon.spy();
|
485
498
|
let targetingData = {
|
486
499
|
uuid: '123'
|
487
500
|
}
|
488
|
-
|
501
|
+
|
489
502
|
sinon.stub(utils, 'sendRequest').callsFake(function(arg1, cb) {
|
490
|
-
let response = JSON.stringify({
|
503
|
+
let response = JSON.stringify({
|
491
504
|
id: '6572251357847878203',
|
492
505
|
impid: 'some-imp-id',
|
493
506
|
price: 10,
|
@@ -498,21 +511,21 @@ describe('nativeAssetManager', () => {
|
|
498
511
|
cid: '9325',
|
499
512
|
crid: '97494204',
|
500
513
|
cat: [ 'IAB3-1' ],
|
501
|
-
ext: {
|
502
|
-
appnexus: {
|
514
|
+
ext: {
|
515
|
+
appnexus: {
|
503
516
|
brand_id: 555545,
|
504
517
|
auction_id: 4550134868038456300,
|
505
518
|
bidder_id: 2,
|
506
|
-
bid_ad_type: 3
|
519
|
+
bid_ad_type: 3
|
507
520
|
}
|
508
521
|
}
|
509
522
|
});
|
510
523
|
cb(response);
|
511
524
|
});
|
512
|
-
|
525
|
+
|
513
526
|
const nativeAssetManager = makeManager();
|
514
527
|
nativeAssetManager.loadMobileAssets(targetingData, cb);
|
515
|
-
|
528
|
+
|
516
529
|
utils.sendRequest.restore();
|
517
530
|
|
518
531
|
expect(win.document.body.innerHTML).to.include('<p>new value</p>');
|
@@ -526,23 +539,23 @@ describe('nativeAssetManager', () => {
|
|
526
539
|
})
|
527
540
|
|
528
541
|
describe('safe frame disabled', () => {
|
529
|
-
|
542
|
+
|
530
543
|
beforeEach(() => {
|
531
544
|
win.parent.frames = [win];
|
532
545
|
win.parent.document = {
|
533
|
-
getElementsByTagName: sinon.stub().returns([{
|
546
|
+
getElementsByTagName: sinon.stub().returns([{
|
534
547
|
contentWindow: win,
|
535
548
|
parentElement: {
|
536
549
|
getBoundingClientRect: () => ({
|
537
550
|
width: 600
|
538
551
|
}),
|
539
552
|
children: [{
|
540
|
-
width: '1',
|
553
|
+
width: '1',
|
541
554
|
height: '1'
|
542
555
|
}]
|
543
556
|
}
|
544
557
|
}])
|
545
|
-
}
|
558
|
+
}
|
546
559
|
})
|
547
560
|
|
548
561
|
it('should set the iframe to the width of the container', () => {
|
@@ -559,7 +572,7 @@ describe('nativeAssetManager', () => {
|
|
559
572
|
adId : AD_ID,
|
560
573
|
adTemplate : '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'
|
561
574
|
};
|
562
|
-
|
575
|
+
|
563
576
|
win.document.body.innerHTML = html;
|
564
577
|
win.addEventListener = createResponder([
|
565
578
|
{ key: 'body', value: 'Body content' },
|
@@ -567,14 +580,149 @@ describe('nativeAssetManager', () => {
|
|
567
580
|
{ key: 'clickUrl', value: 'http://www.example.com' },
|
568
581
|
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
569
582
|
]);
|
570
|
-
|
583
|
+
|
571
584
|
const nativeAssetManager = makeManager();
|
572
585
|
nativeAssetManager.loadAssets(AD_ID);
|
573
|
-
|
586
|
+
|
574
587
|
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
575
588
|
expect(win.document.body.innerHTML).to.include(`<img class="pb-icon" src="http://www.image.com/picture.jpg" alt="icon" height="150" width="50">`);
|
576
589
|
expect(win.document.body.innerHTML).to.include(`<p>Body content</p>`);
|
577
590
|
expect(win.document.body.style.width).to.equal('600px');
|
578
591
|
});
|
579
592
|
});
|
593
|
+
|
594
|
+
describe('loadAssets calls error callback', () => {
|
595
|
+
let recvMessages, reply;
|
596
|
+
|
597
|
+
function mockMessenger() {
|
598
|
+
return function (msg, cb) {
|
599
|
+
reply = cb;
|
600
|
+
recvMessages.push(msg);
|
601
|
+
};
|
602
|
+
}
|
603
|
+
|
604
|
+
beforeEach(() => {
|
605
|
+
recvMessages = [];
|
606
|
+
reply = null;
|
607
|
+
});
|
608
|
+
|
609
|
+
|
610
|
+
it('when there are no assets to load', () => {
|
611
|
+
win.pbNativeData = {adId: 123};
|
612
|
+
const mgr = makeManager(mockMessenger);
|
613
|
+
const cb = sinon.spy();
|
614
|
+
const errCb = sinon.spy();
|
615
|
+
mgr.loadAssets(123, cb, errCb);
|
616
|
+
expect(cb.called).to.be.false;
|
617
|
+
expect(errCb.called).to.be.true;
|
618
|
+
});
|
619
|
+
|
620
|
+
Object.entries({
|
621
|
+
'all assets': {
|
622
|
+
adId: 123,
|
623
|
+
requestAllAssets: true
|
624
|
+
},
|
625
|
+
'some assets': {
|
626
|
+
adId: 123,
|
627
|
+
}
|
628
|
+
}).forEach(([t, pbData]) => {
|
629
|
+
describe(t, () => {
|
630
|
+
let mgr;
|
631
|
+
beforeEach(() => {
|
632
|
+
win.pbNativeData = pbData;
|
633
|
+
win.document.body.innerHTML = '##hb_native_title##';
|
634
|
+
mgr = makeManager({}, mockMessenger);
|
635
|
+
});
|
636
|
+
|
637
|
+
it('on response "timeout"', () => {
|
638
|
+
const cb = sinon.spy();
|
639
|
+
const err = sinon.spy();
|
640
|
+
mgr.loadAssets(123, cb, err);
|
641
|
+
for (let i = 0; i < 12; i++) {
|
642
|
+
reply({data: 'invalid'});
|
643
|
+
}
|
644
|
+
expect(cb.called).to.be.false;
|
645
|
+
expect(err.called).to.be.true;
|
646
|
+
});
|
647
|
+
|
648
|
+
it('on rendering exceptions', () => {
|
649
|
+
const cb = sinon.spy();
|
650
|
+
const err = sinon.spy();
|
651
|
+
mgr.loadAssets(123, cb, err);
|
652
|
+
win.renderAd = () => {
|
653
|
+
throw new Error();
|
654
|
+
};
|
655
|
+
reply({
|
656
|
+
data: JSON.stringify({
|
657
|
+
message: 'assetResponse',
|
658
|
+
adId: 123,
|
659
|
+
rendererUrl: 'mock-render'
|
660
|
+
})
|
661
|
+
});
|
662
|
+
expect(cb.called).to.be.false;
|
663
|
+
expect(err.called).to.be.true;
|
664
|
+
});
|
665
|
+
});
|
666
|
+
});
|
667
|
+
});
|
668
|
+
|
669
|
+
describe('GAM macro %%CLICK_URL_UNESC%%', () => {
|
670
|
+
it("should remove %%CLICK_URL_UNESC%% if there's no variable set", () => {
|
671
|
+
const html = `<script>
|
672
|
+
let nativeTag = {};
|
673
|
+
nativeTag.adTemplate = "<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"%%CLICK_URL_UNESC%%##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>";
|
674
|
+
nativeTag.pubUrl = "https://www.url.com";
|
675
|
+
nativeTag.adId = "`+AD_ID+`";
|
676
|
+
nativeTag.requestAllAssets = true;
|
677
|
+
window.pbNativeTag.renderNativeAd(nativeTag);
|
678
|
+
</script>`;
|
679
|
+
win.pbNativeData = {
|
680
|
+
pubUrl : 'https://www.url.com',
|
681
|
+
adId : AD_ID,
|
682
|
+
adTemplate : '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"%%CLICK_URL_UNESC%%##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'
|
683
|
+
};
|
684
|
+
|
685
|
+
win.document.body.innerHTML = html;
|
686
|
+
win.addEventListener = createResponder([
|
687
|
+
{ key: 'body', value: 'Body content' },
|
688
|
+
{ key: 'title', value: 'new value' },
|
689
|
+
{ key: 'clickUrl', value: 'http://www.example.com' },
|
690
|
+
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
691
|
+
]);
|
692
|
+
|
693
|
+
const nativeAssetManager = makeManager();
|
694
|
+
nativeAssetManager.loadAssets(AD_ID);
|
695
|
+
|
696
|
+
expect(win.document.body.innerHTML).to.include(`<a href="http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
697
|
+
});
|
698
|
+
|
699
|
+
it("should substitute %%CLICK_URL_UNESC%% with clickUrlUnesc value", () => {
|
700
|
+
const html = `<script>
|
701
|
+
let nativeTag = {};
|
702
|
+
nativeTag.adTemplate = "<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"%%CLICK_URL_UNESC%%##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>";
|
703
|
+
nativeTag.pubUrl = "https://www.url.com";
|
704
|
+
nativeTag.adId = "`+AD_ID+`";
|
705
|
+
nativeTag.requestAllAssets = true;
|
706
|
+
window.pbNativeTag.renderNativeAd(nativeTag);
|
707
|
+
</script>`;
|
708
|
+
win.pbNativeData = {
|
709
|
+
pubUrl : 'https://www.url.com',
|
710
|
+
adId : AD_ID,
|
711
|
+
adTemplate : '<div class=\"sponsored-post\">\r\n <div class=\"thumbnail\"><\/div>\r\n <div class=\"content\">\r\n <h1>\r\n <a href=\"%%CLICK_URL_UNESC%%##hb_native_linkurl##\" target=\"_blank\" class=\"pb-click\">##hb_native_title##<\/a>\r\n <\/h1>\r\n <p>##hb_native_body##<\/p>\r\n \t<div class=\"attribution\">\r\n \t<img class=\"pb-icon\" src=\"##hb_native_image##\" alt=\"icon\" height=\"150\" width=\"50\">\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>',
|
712
|
+
};
|
713
|
+
|
714
|
+
win.document.body.innerHTML = html;
|
715
|
+
win.addEventListener = createResponder([
|
716
|
+
{ key: 'body', value: 'Body content' },
|
717
|
+
{ key: 'title', value: 'new value' },
|
718
|
+
{ key: 'clickUrl', value: 'http://www.example.com' },
|
719
|
+
{ key: 'image', value: 'http://www.image.com/picture.jpg' },
|
720
|
+
], null, null, );
|
721
|
+
|
722
|
+
const nativeAssetManager = makeManager({ clickUrlUnesc: 'https://will.redirect/?to='});
|
723
|
+
nativeAssetManager.loadAssets(AD_ID);
|
724
|
+
|
725
|
+
expect(win.document.body.innerHTML).to.include(`<a href="https://will.redirect/?to=http://www.example.com" target="_blank" class="pb-click">new value</a>`);
|
726
|
+
});
|
727
|
+
});
|
580
728
|
});
|