From 9b3901e102b085e14ed4c5d87179745a04dae5dd Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Mon, 22 Jun 2020 15:39:50 -0400 Subject: [PATCH 01/14] PUC update to include Native Phase 2 spec: 1) Added renderNativeAd function to nativeTrackerManager.js 2) renderNativeAd checks for existence of adId and performs the following: - Checks for rendererUrl and preloads if exists - Uses prexisting loadAssets function with new callback - Fires Impression tracker and loads click tracker 3) LoadAssets update: - Checks for existence of assetsToReplace and adds each asset to placeholder - If no placeholders exist, checks for requestAllAssets flag to fire new requestAllAssets function 4) requestAllAssets will postmessage Prebid using the action allAssetRequest instead of assetRequest 5) Replace assets will now use added logic: - If rendererUrl existence. If exists in adServer (preloaded) then check for renderAd availability on the window. If none exists, set load event on the script tag using the id 'pb-native-renderer'. If url sent as asset from Prebid, append script to window and attach load event. When script loaded and renderAd available, fire function to retrieve HTML. This inserted into innerHtml - Else if adTemplate exists, replace assets and insert into innerHtml - Else run existing replace method 6) replace function updated to include check for new native to replace keys which are in the format of ##KEY## nativeAssetManager_spec and nativeTrackerManager_spec both updated to include additional tests nativeTracker.js updated to include renderNativeAd function definition on window object --- .DS_Store | Bin 0 -> 10244 bytes dist/load-cookie.html | 16 ++ package-lock.json | 200 +++++++++++++++-------- src/nativeAssetManager.js | 96 ++++++++++-- src/nativeTrackerManager.js | 44 +++++- src/nativeTrackers.js | 4 +- test/spec/nativeAssetManager_spec.js | 209 ++++++++++++++++++++++++- test/spec/nativeTrackerManager_spec.js | 58 +++++++ 8 files changed, 546 insertions(+), 81 deletions(-) create mode 100644 .DS_Store create mode 100755 dist/load-cookie.html diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..03dd42d786cf4337861c940bf810b391df4ef6ce GIT binary patch literal 10244 zcmeHMJ!~9B6n<-;&wI9`*aYE{l@L;djAcWV#6n2t^I6EkfrvvOlpy`+<}ikx!x;HXeXO)(r9j&_gTVT;NRrIq32$Z&GhlN~ifam3RR=LvUmiqhJnWxz6! zW}t*yF0E3Hs@S#pdo74+Xyec673}B#5gX2k3h=K}lV|#v@B4htGkz`Nn@2|k2kVu3 z)M|^2lwZlt+ltC%mDl}k{@O2pz5e6oB+tfw^lTsMPZs?}4iz1sqMliYvz(|S_A}5g ze)=o?;x--gAJ3H@D9l>>7-?3!fp6&^Qq$}RA01MkY6+CL6DSkj23DH+I-O5PeCu4y zaw1PF8snbqWuT`uMn4y$Z-V8JA}GgC)bMAbhCE_II-=HSJxNm+>+!Cp$1_lF2U!Qy zg&I3JuF?%0BMQx@5bIKpoIzwC?>(S~=_%g)1kc)_+g50PsTWE8!xYTmoJ{Ic*h$TURv=kZLFW16x`+K z*I(V)Z+-Of@h2y@?xJpNjv74ath|noU*JsR!ca_p>!R7JtL51jzQ4VBMSPQ5ysngN z4?`vSAp_Ckk1Cxoh{6NhWyCpZ;2m{SUnlEce@C&OfuEjXzqn0D|M{1H-}r1-px4^R zD$i;+kduehG!Iqxp`kW?AhhI5{UsE|3fIw|qnqe+J5YEP{&iL>;#bA>O`&6hqh>&-k=I?C%mC|!+Sw|eGO#a!*e3=%D8>%nsKatBW?+`Re_NaAHe@b zL`C9y!k6ZNb0fn-BEzIOuw=v)=q=Q?NoBeM%j_h+RKduH8Y54Mh+Po{Mo{Th+<8-Q zQ~^g>IhZFsM*;5ztf0m|&gv5wdPIb&Lgy>I|BSr49t+>aeQ&1cSed7Lni>@&+%&3D zEA!)?RJ#YYY$_zaqAdiy464>dm@*5;I;*A1W*>v6FOuy==f6p zCemphuTwrc=Kjp}(Qk+hzcKpL{ERx}bR{S1NcB)co4;$?jQvd9;XZK3Z93kc-;42T z?PHu-?IyklNDbXF&%h_XLjHmiUp$YDj*c`V!o+;^Fgve~e(6q(J|mw#N}TR#R`df` zw1Cl`M}^4fJ2C1f6vRE5Ue{T~`55&_{h8kLrlYwR)1Ì!pv1}pn$Icu34W$(!IIs)f7t8Uu;N|%9 z>Yi8xQs+fwhti60#EEcNxtjmK{}~|HHr=fGz5c5-tKIx9>Twx%{-0WDv-5xIn)9W{ HZT|l+M$DcO literal 0 HcmV?d00001 diff --git a/dist/load-cookie.html b/dist/load-cookie.html new file mode 100755 index 00000000..98bf7a1c --- /dev/null +++ b/dist/load-cookie.html @@ -0,0 +1,16 @@ + + + + + + + Document + + + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d816842c..d02ab05e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid-universal-creative", - "version": "1.6.0-pre", + "version": "1.9.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -4594,25 +4594,29 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "optional": true, "requires": { @@ -4622,13 +4626,15 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "bundled": true, + "resolved": false, + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, "requires": { @@ -4638,37 +4644,43 @@ }, "chownr": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "optional": true, "requires": { @@ -4677,25 +4689,29 @@ }, "deep-extend": { "version": "0.6.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, "requires": { @@ -4704,13 +4720,15 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "bundled": true, + "resolved": false, + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, "requires": { @@ -4726,7 +4744,8 @@ }, "glob": { "version": "7.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "optional": true, "requires": { @@ -4740,13 +4759,15 @@ }, "has-unicode": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "bundled": true, + "resolved": false, + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "optional": true, "requires": { @@ -4755,7 +4776,8 @@ }, "ignore-walk": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, "requires": { @@ -4764,7 +4786,8 @@ }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, "requires": { @@ -4774,19 +4797,22 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "optional": true, "requires": { @@ -4795,13 +4821,15 @@ }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, "requires": { @@ -4810,13 +4838,15 @@ }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": false, + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true, "optional": true }, "minipass": { "version": "2.3.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, "optional": true, "requires": { @@ -4826,7 +4856,8 @@ }, "minizlib": { "version": "1.2.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "dev": true, "optional": true, "requires": { @@ -4835,7 +4866,8 @@ }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "optional": true, "requires": { @@ -4844,13 +4876,15 @@ }, "ms": { "version": "2.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true, "optional": true }, "needle": { "version": "2.3.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", "dev": true, "optional": true, "requires": { @@ -4861,7 +4895,8 @@ }, "node-pre-gyp": { "version": "0.12.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", "dev": true, "optional": true, "requires": { @@ -4879,7 +4914,8 @@ }, "nopt": { "version": "4.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, "requires": { @@ -4889,13 +4925,15 @@ }, "npm-bundled": { "version": "1.0.6", - "bundled": true, + "resolved": false, + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "optional": true, "requires": { @@ -4905,7 +4943,8 @@ }, "npmlog": { "version": "4.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, "requires": { @@ -4917,19 +4956,22 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "optional": true, "requires": { @@ -4938,19 +4980,22 @@ }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "bundled": true, + "resolved": false, + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, "requires": { @@ -4960,19 +5005,22 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "bundled": true, + "resolved": false, + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "optional": true, "requires": { @@ -4984,7 +5032,8 @@ "dependencies": { "minimist": { "version": "1.2.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true } @@ -4992,7 +5041,8 @@ }, "readable-stream": { "version": "2.3.6", - "bundled": true, + "resolved": false, + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, "requires": { @@ -5007,7 +5057,8 @@ }, "rimraf": { "version": "2.6.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "optional": true, "requires": { @@ -5016,43 +5067,50 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "bundled": true, + "resolved": false, + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "bundled": true, + "resolved": false, + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.7.0", - "bundled": true, + "resolved": false, + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": false, + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "optional": true, "requires": { @@ -5063,7 +5121,8 @@ }, "string_decoder": { "version": "1.1.1", - "bundled": true, + "resolved": false, + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, "requires": { @@ -5072,7 +5131,8 @@ }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "optional": true, "requires": { @@ -5081,13 +5141,15 @@ }, "strip-json-comments": { "version": "2.0.1", - "bundled": true, + "resolved": false, + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.8", - "bundled": true, + "resolved": false, + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "dev": true, "optional": true, "requires": { @@ -5102,13 +5164,15 @@ }, "util-deprecate": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "optional": true, "requires": { @@ -5117,13 +5181,15 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": false, + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true }, "yallist": { "version": "3.0.3", - "bundled": true, + "resolved": false, + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true, "optional": true } diff --git a/src/nativeAssetManager.js b/src/nativeAssetManager.js index 2fd91d0b..2819d86c 100644 --- a/src/nativeAssetManager.js +++ b/src/nativeAssetManager.js @@ -3,7 +3,7 @@ * values in native creative templates. */ -import { sendRequest } from './utils'; +import { sendRequest, loadScript } from './utils'; /* * Native asset->key mapping from Prebid.js/src/constants.json @@ -27,6 +27,7 @@ const NATIVE_KEYS = { phone: 'hb_native_phone', price: 'hb_native_price', salePrice: 'hb_native_saleprice', + rendererUrl: 'hb_renderer_url', }; // Asset type mapping as per Native IAB spec 1.2 @@ -160,14 +161,26 @@ export function newNativeAssetManager(win) { /* * Entry point to search for placeholderes and set up postmessage roundtrip * to retrieve native assets. Looks for placeholders for the given adId and - * fires a callback after the native html is updated. + * fires a callback after the native html is updated. If no placeholders found + * and requestAllAssets flag is set in the tag, postmessage roundtrip + * to retrieve native assets that have a value on the corresponding bid */ function loadAssets(adId, cb) { - const placeholders = scanForPlaceholders(adId); + const placeholders = scanForPlaceholders(adId), flag = (typeof win.pbNativeData !== 'undefined'); + + if(flag && win.pbNativeData.hasOwnProperty('assetsToReplace')) { + win.pbNativeData.assetsToReplace.forEach((asset) => { + const key = (asset.match(/hb_native_/i)) ? asset : NATIVE_KEYS[asset]; + if(key) {placeholders.push(key);} + }); + } if (placeholders.length > 0) { callback = cb; requestAssets(adId, placeholders); + }else if(flag && win.pbNativeData.hasOwnProperty('requestAllAssets') && win.pbNativeData.requestAllAssets) { + callback = cb; + requestAllAssets(adId); } } @@ -176,10 +189,11 @@ export function newNativeAssetManager(win) { */ function scanForPlaceholders(adId) { let placeholders = []; + const flag = (typeof win.pbNativeData !== 'undefined'); Object.keys(NATIVE_KEYS).forEach(key => { const placeholderKey = NATIVE_KEYS[key]; - const placeholder = (adId) ? `${placeholderKey}:${adId}` : `${placeholderKey}`; + const placeholder = (adId && !flag) ? `${placeholderKey}:${adId}` : `${placeholderKey}`; const placeholderIndex = win.document.body.innerHTML.indexOf(placeholder); if (~placeholderIndex) { @@ -190,6 +204,19 @@ export function newNativeAssetManager(win) { return placeholders; } + /* + * Searches the DOM for existence passed string + */ + function scanForString(str) { + const strIndex = win.document.body.innerHTML.indexOf(str); + + if (~strIndex) { + return true; + } + + return false; + } + /* * Sends postmessage to Prebid for asset placeholders found in the native * creative template, and setups up a listener for when Prebid responds. @@ -204,6 +231,23 @@ export function newNativeAssetManager(win) { assets, }; + + win.parent.postMessage(JSON.stringify(message), '*'); + } + + /* + * Sends postmessage to Prebid for asset placeholders found in the native + * creative template, and setups up a listener for when Prebid responds. + */ + function requestAllAssets(adId) { + win.addEventListener('message', replaceAssets, false); + + const message = { + message: 'Prebid Native', + action: 'allAssetRequest', + adId, + }; + win.parent.postMessage(JSON.stringify(message), '*'); } @@ -227,12 +271,43 @@ export function newNativeAssetManager(win) { } if (data.message === 'assetResponse') { - const body = win.document.body.innerHTML; - const newHtml = replace(body, data); + const body = win.document.body.innerHTML,flag = (typeof win.pbNativeData !== 'undefined'); - win.document.body.innerHTML = newHtml; - callback && callback(); - win.removeEventListener('message', replaceAssets); + if((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (flag && win.pbNativeData.hasOwnProperty('rendererUrl'))) { + if(win.renderAd){ + const newHtml = (win.renderAd && win.renderAd(data.assets)) || ''; + win.document.body.innerHTML = body + newHtml; + callback && callback(); + win.removeEventListener('message', replaceAssets); + } else if(document.getElementById('pb-native-renderer')) { + document.getElementById('pb-native-renderer').addEventListener('load', function() { + const newHtml = (win.renderAd && win.renderAd(data.assets)) || ''; + win.document.body.innerHTML = body + newHtml; + callback && callback(); + win.removeEventListener('message', replaceAssets); + }); + } else { + loadScript(win, ((flag && win.pbNativeData.hasOwnProperty('rendererUrl') && win.pbNativeData.rendererUrl) || data.rendererUrl), function(){ + const newHtml = (win.renderAd && win.renderAd(data.assets)) || ''; + win.document.body.innerHTML = body + newHtml; + callback && callback(); + win.removeEventListener('message', replaceAssets); + }) + } + } else if((data.hasOwnProperty('adTemplate') && data.adTemplate)||(flag && win.pbNativeData.hasOwnProperty('adTemplate'))) { + const template = (flag && win.pbNativeData.hasOwnProperty('adTemplate') && win.pbNativeData.adTemplate) || data.adTemplate; + const newHtml = replace(template, data); + + win.document.body.innerHTML = body + newHtml; + callback && callback(); + win.removeEventListener('message', replaceAssets); + } else { + const newHtml = replace(body, data); + + win.document.body.innerHTML = newHtml; + callback && callback(); + win.removeEventListener('message', replaceAssets); + } } } @@ -244,7 +319,8 @@ export function newNativeAssetManager(win) { let html = document; (assets || []).forEach(asset => { - const searchString = (adId) ? `${NATIVE_KEYS[asset.key]}:${adId}` : `${NATIVE_KEYS[asset.key]}`; + const flag = (typeof win.pbNativeData !== 'undefined'); + const searchString = (adId && !flag) ? `${NATIVE_KEYS[asset.key]}:${adId}` : ((flag) ? '##'+`${NATIVE_KEYS[asset.key]}`+'##' : `${NATIVE_KEYS[asset.key]}`); const searchStringRegex = new RegExp(searchString, 'g'); html = html.replace(searchStringRegex, asset.value); }); diff --git a/src/nativeTrackerManager.js b/src/nativeTrackerManager.js index a8bb9dba..11b341f1 100644 --- a/src/nativeTrackerManager.js +++ b/src/nativeTrackerManager.js @@ -10,6 +10,7 @@ const AD_DATA_ADID_ATTRIBUTE = 'pbAdId'; export function newNativeTrackerManager(win) { let publisherDomain; + function findAdElements(className) { let adElements = win.document.getElementsByClassName(className); return adElements || []; @@ -67,6 +68,24 @@ export function newNativeTrackerManager(win) { } } + function fireNativeImpTracker(adId){ + let parsedUrl = parseUrl(window.pbNativeData.pubUrl); + publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host; + fireTracker(adId, 'impression'); + } + + function fireNativeCallback(){ + let parsedUrl = parseUrl(window.pbNativeData.pubUrl); + publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host; + + const adElements = findAdElements(AD_ANCHOR_CLASS_NAME); + for (let i = 0; i < adElements.length; i++) { + adElements[i].addEventListener('click', function(event) { + loadClickTrackers(event, window.pbNativeData.adId); + }, true); + } + } + // START OF MAIN CODE let startTrackers = function (dataObject) { const targetingData = transformAuctionTargetingData(dataObject); @@ -103,7 +122,30 @@ export function newNativeTrackerManager(win) { } } + //Native Render Ad Function + let renderNativeAd = function(nativeTag){ + window.pbNativeData = nativeTag; + const nativeAssetManager = newNativeAssetManager(window); + + if(nativeTag.hasOwnProperty('adId')) { + if(nativeTag.hasOwnProperty('rendererUrl') && !nativeTag.rendererUrl.match(/##.*##/i)){ + const scr = document.createElement('SCRIPT'); + scr.src = nativeTag.rendererUrl, + scr.id = 'pb-native-renderer'; + document.body.appendChild(scr); + } + nativeAssetManager.loadAssets(nativeTag.adId,fireNativeCallback); + fireNativeCallback(); + fireNativeImpTracker(nativeTag.adId); + }else{ + console.warn('Prebid Native Tag object was missing \'adId\'.'); + } + + + } + return { - startTrackers + startTrackers, + renderNativeAd } } diff --git a/src/nativeTrackers.js b/src/nativeTrackers.js index e2e0c428..192c3f49 100644 --- a/src/nativeTrackers.js +++ b/src/nativeTrackers.js @@ -3,4 +3,6 @@ import { newNativeTrackerManager } from './nativeTrackerManager'; window.pbNativeTag = (window.pbNativeTag || {}); const nativeTrackerManager = newNativeTrackerManager(window); -window.pbNativeTag.startTrackers = nativeTrackerManager.startTrackers; \ No newline at end of file +window.pbNativeTag.startTrackers = nativeTrackerManager.startTrackers; +window.pbNativeTag.renderNativeAd = nativeTrackerManager.renderNativeAd; + diff --git a/test/spec/nativeAssetManager_spec.js b/test/spec/nativeAssetManager_spec.js index 4b5098e0..081ebe54 100644 --- a/test/spec/nativeAssetManager_spec.js +++ b/test/spec/nativeAssetManager_spec.js @@ -5,6 +5,26 @@ import { mocks } from 'test/helpers/mocks'; import * as utils from 'src/utils'; const AD_ID = 'abc123'; +const NATIVE_KEYS = { + title: 'hb_native_title', + body: 'hb_native_body', + body2: 'hb_native_body2', + privacyLink: 'hb_native_privacy', + sponsoredBy: 'hb_native_brand', + image: 'hb_native_image', + icon: 'hb_native_icon', + clickUrl: 'hb_native_linkurl', + displayUrl: 'hb_native_displayurl', + cta: 'hb_native_cta', + rating: 'hb_native_rating', + address: 'hb_native_address', + downloads: 'hb_native_downloads', + likes: 'hb_native_likes', + phone: 'hb_native_phone', + price: 'hb_native_price', + salePrice: 'hb_native_saleprice', + rendererUrl: 'hb_renderer_url', +}; const mockDocument = { getWindowObject: function() { @@ -17,15 +37,38 @@ const mockDocument = { }; // creates mock postmessage response from prebid's native.js:getAssetMessage -function createResponder(assets) { +function createResponder(assets,url,template) { + return function(type, listener) { + if (type !== 'message') { return; } + + const data = { message: 'assetResponse', adId: AD_ID, assets, adTemplate:template, rendererUrl:url }; + listener({ data: JSON.stringify(data) }); + }; +} + +// creates mock postmessage response from prebid's native.js:getAssetMessage +function createAllResponder(assets,url,template) { return function(type, listener) { if (type !== 'message') { return; } - const data = { message: 'assetResponse', adId: AD_ID, assets }; + const data = { message: 'assetResponse', adId: AD_ID, assets, adTemplate:template, rendererUrl:url }; listener({ data: JSON.stringify(data) }); }; } +// creates mock html markup responsse from renderUrl +function generateRenderer(assets) { + let newhtml = '
\r\n
<\/div>\r\n
\r\n

\r\n ##hb_native_title##<\/a>\r\n <\/h1>\r\n

##hb_native_body##<\/p>\r\n \t

\r\n \t\"icon\"\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'; + + (assets || []).forEach(asset => { + const searchString = '##'+`${NATIVE_KEYS[asset.key]}`+'##'; + const searchStringRegex = new RegExp(searchString, 'g'); + newhtml = newhtml.replace(searchStringRegex, asset.value); + }); + + return newhtml; +} + describe('nativeTrackerManager', () => { let win; @@ -84,6 +127,168 @@ describe('nativeTrackerManager', () => { expect(win.removeEventListener.callCount).to.equal(1); }); + it('replaces native placeholders with their asset values from adTemplate', () => { + const html = ``; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : AD_ID, + adTemplate : '
\r\n
<\/div>\r\n
\r\n

\r\n ##hb_native_title##<\/a>\r\n <\/h1>\r\n

##hb_native_body##<\/p>\r\n \t

\r\n \t\"icon\"\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>' + }; + + win.document.body.innerHTML = html; + win.addEventListener = createResponder([ + { key: 'body', value: 'Body content' }, + { key: 'title', value: 'new value' }, + { key: 'clickUrl', value: 'http://www.example.com' }, + { key: 'image', value: 'http://www.image.com/picture.jpg' }, + ]); + + const nativeAssetManager = newNativeAssetManager(win); + nativeAssetManager.loadAssets(AD_ID); + + expect(win.document.body.innerHTML).to.include(`new value`); + expect(win.document.body.innerHTML).to.include(`icon`); + expect(win.document.body.innerHTML).to.include(`

Body content

`); + }); + + it('loads rendererUrl and passes assets to renderAd - writes response to innerHtml', () => { + const html = ``; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : AD_ID, + rendererUrl : 'https://www.renderer.com/render.js', + requestAllAssets : true + }; + + win.document.body.innerHTML = html; + win.renderAd = generateRenderer; + + win.addEventListener = createAllResponder([ + { key: 'body', value: 'Body content' }, + { key: 'title', value: 'new value' }, + { key: 'clickUrl', value: 'http://www.example.com' }, + { key: 'image', value: 'http://www.image.com/picture.jpg' }, + ],null,null); + + const nativeAssetManager = newNativeAssetManager(win); + nativeAssetManager.loadAssets(AD_ID); + + expect(win.document.body.innerHTML).to.include(`new value`); + expect(win.document.body.innerHTML).to.include(`icon`); + expect(win.document.body.innerHTML).to.include(`

Body content

`); + }); + + it('no placeholders found but requests all assets flag set - rendererUrl', () => { + const html = ``, + url = 'https://www.renderer.com/render.js'; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : AD_ID, + rendererUrl : 'https://www.renderer.com/render.js', + requestAllAssets : true + }; + + win.document.body.innerHTML = html; + win.renderAd = generateRenderer; + + win.addEventListener = createAllResponder([ + { key: 'body', value: 'Body content' }, + { key: 'title', value: 'new value' }, + { key: 'clickUrl', value: 'http://www.example.com' }, + { key: 'image', value: 'http://www.image.com/picture.jpg' }, + ],url,null); + + const nativeAssetManager = newNativeAssetManager(win); + nativeAssetManager.loadAssets(AD_ID); + + expect(win.document.body.innerHTML).to.include(`new value`); + expect(win.document.body.innerHTML).to.include(`icon`); + expect(win.document.body.innerHTML).to.include(`

Body content

`); + }); + + it('no placeholders found but requests all assets flag set - adTemplate', () => { + const html = ``, + template = '
\r\n
<\/div>\r\n
\r\n

\r\n ##hb_native_title##<\/a>\r\n <\/h1>\r\n

##hb_native_body##<\/p>\r\n \t

\r\n \t\"icon\"\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : AD_ID, + requestAllAssets : true + }; + + win.document.body.innerHTML = html; + + win.addEventListener = createAllResponder([ + { key: 'body', value: 'Body content' }, + { key: 'title', value: 'new value' }, + { key: 'clickUrl', value: 'http://www.example.com' }, + { key: 'image', value: 'http://www.image.com/picture.jpg' }, + ],null,template); + + const nativeAssetManager = newNativeAssetManager(win); + nativeAssetManager.loadAssets(AD_ID); + + expect(win.document.body.innerHTML).to.include(`new value`); + expect(win.document.body.innerHTML).to.include(`icon`); + expect(win.document.body.innerHTML).to.include(`

Body content

`); + }); + + it('no placeholders found but assets defined in nativeTag - adTemplate', () => { + const html = ``, + template = '
\r\n
<\/div>\r\n
\r\n

\r\n ##hb_native_title##<\/a>\r\n <\/h1>\r\n

##hb_native_body##<\/p>\r\n \t

\r\n \t\"icon\"\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : AD_ID, + assetsToReplace: ['image','hb_native_body','clickUrl','hb_native_title'] + }; + + win.document.body.innerHTML = html; + + win.addEventListener = createAllResponder([ + { key: 'body', value: 'Body content' }, + { key: 'title', value: 'new value' }, + { key: 'clickUrl', value: 'http://www.example.com' }, + { key: 'image', value: 'http://www.image.com/picture.jpg' }, + ],null,template); + + const nativeAssetManager = newNativeAssetManager(win); + nativeAssetManager.loadAssets(AD_ID); + + expect(win.document.body.innerHTML).to.include(`new value`); + expect(win.document.body.innerHTML).to.include(`icon`); + expect(win.document.body.innerHTML).to.include(`

Body content

`); + }); + it('does not replace anything if no placeholders found', () => { const html = `

Native Ad

diff --git a/test/spec/nativeTrackerManager_spec.js b/test/spec/nativeTrackerManager_spec.js index b82e803e..dc0b44ad 100644 --- a/test/spec/nativeTrackerManager_spec.js +++ b/test/spec/nativeTrackerManager_spec.js @@ -27,6 +27,12 @@ describe('nativeTrackerManager', function () { pubUrl: 'http://example.com' }; + let tagDataAlt = { + pubUrl: 'http://example.com', + adId: 'ad123', + assetsToReplace: ['image','hb_native_linkurl','body','title'], + }; + beforeEach(function () { mockWin = merge(mocks.createFakeWindow(tagData.pubUrl), renderingMocks.getWindowObject()); consoleWarn = sinon.stub(console, 'warn'); @@ -89,6 +95,58 @@ describe('nativeTrackerManager', function () { expect(trimPort(postMessageTargetDomain)).to.equal(tagData.pubUrl); }); + it('should verify the postMessage for impression trackers was executed', function() { + mockWin.document.getElementsByClassName = () => [{ + attributes: { + pbAdId: { + value: 'ad123' + } + }, + addEventListener: (type, listener, capture) => { + }, + }]; + let nativeTracker = new newNativeTrackerManager(mockWin); + nativeTracker.renderNativeAd(tagDataAlt); + + expect(mockWin.parent.postMessage.callCount).to.equal(1); + let postMessageTargetDomain = mockWin.parent.postMessage.args[0][1]; + let postMessageContents = mockWin.parent.postMessage.args[0][0]; + let rawPostMessage = JSON.parse(postMessageContents); + + expect(rawPostMessage.message).to.exist.and.to.equal("Prebid Native"); + expect(rawPostMessage.adId).to.exist.and.to.equal("ad123"); + expect(rawPostMessage.action).to.not.exist; + expect(trimPort(postMessageTargetDomain)).to.equal(tagDataAlt.pubUrl); + }); + + it('should verify the postMessages for the impression and click trackers were executed', function() { + mockWin.document.getElementsByClassName = () => [{ + attributes: { + pbAdId: { + value: 'ad123' + } + }, + addEventListener: ((type, listener, capture) => { + listener({ + }) + }) + }]; + + let nativeTracker = new newNativeTrackerManager(mockWin); + nativeTracker.renderNativeAd(tagDataAlt); + + expect(mockWin.parent.postMessage.callCount).to.equal(2); + + let postMessageTargetDomain = mockWin.parent.postMessage.args[0][1]; + let postMessageContents = mockWin.parent.postMessage.args[0][0]; + let rawPostMessage = JSON.parse(postMessageContents); + + expect(rawPostMessage.message).to.exist.and.to.equal("Prebid Native"); + expect(rawPostMessage.adId).to.exist.and.to.equal("ad123"); + expect(rawPostMessage.action).to.exist.and.to.equal('click'); + expect(trimPort(postMessageTargetDomain)).to.equal(tagDataAlt.pubUrl); + }); + it('should verify 2 warning messages (one for impression, one for click) was executed', function() { mockWin.document.getElementsByClassName = () => [{ addEventListener: ((type, listener, capture) => { From 1e220d4610c19f6a287301187061cb6048fc5e6e Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Wed, 24 Jun 2020 16:43:33 -0400 Subject: [PATCH 02/14] Update to separate renderNative method into new class called nativeRenderManager. Removed repetitive publisherDomain definitions --- src/nativeRenderManager.js | 78 +++++++++++++++++++++ src/nativeTrackerManager.js | 43 +----------- src/nativeTrackers.js | 4 +- test/spec/nativeRenderManager_spec.js | 93 ++++++++++++++++++++++++++ test/spec/nativeTrackerManager_spec.js | 4 +- 5 files changed, 177 insertions(+), 45 deletions(-) create mode 100644 src/nativeRenderManager.js create mode 100644 test/spec/nativeRenderManager_spec.js diff --git a/src/nativeRenderManager.js b/src/nativeRenderManager.js new file mode 100644 index 00000000..8c90a853 --- /dev/null +++ b/src/nativeRenderManager.js @@ -0,0 +1,78 @@ +/* + * Script to handle firing impression and click trackers from native teamplates + */ +import { parseUrl, triggerPixel, transformAuctionTargetingData } from './utils'; +import { newNativeAssetManager } from './nativeAssetManager'; + +const AD_ANCHOR_CLASS_NAME = 'pb-click'; +const AD_DATA_ADID_ATTRIBUTE = 'pbAdId'; + +export function newNativeRenderManager(win) { + let publisherDomain; + + + function findAdElements(className) { + let adElements = win.document.getElementsByClassName(className); + return adElements || []; + } + + function loadClickTrackers(event, adId) { + fireTracker(adId, 'click'); + } + + function fireTracker(adId, action) { + if (adId === '') { + console.warn('Prebid tracking event was missing \'adId\'. Was adId macro set in the HTML attribute ' + AD_DATA_ADID_ATTRIBUTE + 'on the ad\'s anchor element'); + } else { + let message = { message: 'Prebid Native', adId: adId }; + + // fires click trackers when called via link + if (action === 'click') { + message.action = 'click'; + } + + win.parent.postMessage(JSON.stringify(message), publisherDomain); + } + } + + function fireNativeImpTracker(adId){ + fireTracker(adId, 'impression'); + } + + function fireNativeCallback(){ + const adElements = findAdElements(AD_ANCHOR_CLASS_NAME); + for (let i = 0; i < adElements.length; i++) { + adElements[i].addEventListener('click', function(event) { + loadClickTrackers(event, window.pbNativeData.adId); + }, true); + } + } + + // START OF MAIN CODE + let renderNativeAd = function(nativeTag){ + window.pbNativeData = nativeTag; + const targetingData = transformAuctionTargetingData(nativeTag); + const nativeAssetManager = newNativeAssetManager(window); + + if(nativeTag.hasOwnProperty('adId')) { + let parsedUrl = parseUrl(window.pbNativeData.pubUrl); + publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host; + + if(nativeTag.hasOwnProperty('rendererUrl') && !nativeTag.rendererUrl.match(/##.*##/i)){ + const scr = document.createElement('SCRIPT'); + scr.src = nativeTag.rendererUrl, + scr.id = 'pb-native-renderer'; + document.body.appendChild(scr); + } + nativeAssetManager.loadAssets(nativeTag.adId,fireNativeCallback); + fireNativeCallback(); + fireNativeImpTracker(nativeTag.adId); + }else{ + console.warn('Prebid Native Tag object was missing \'adId\'.'); + } + } + + return { + renderNativeAd + } +} diff --git a/src/nativeTrackerManager.js b/src/nativeTrackerManager.js index 11b341f1..81d97e78 100644 --- a/src/nativeTrackerManager.js +++ b/src/nativeTrackerManager.js @@ -68,24 +68,6 @@ export function newNativeTrackerManager(win) { } } - function fireNativeImpTracker(adId){ - let parsedUrl = parseUrl(window.pbNativeData.pubUrl); - publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host; - fireTracker(adId, 'impression'); - } - - function fireNativeCallback(){ - let parsedUrl = parseUrl(window.pbNativeData.pubUrl); - publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host; - - const adElements = findAdElements(AD_ANCHOR_CLASS_NAME); - for (let i = 0; i < adElements.length; i++) { - adElements[i].addEventListener('click', function(event) { - loadClickTrackers(event, window.pbNativeData.adId); - }, true); - } - } - // START OF MAIN CODE let startTrackers = function (dataObject) { const targetingData = transformAuctionTargetingData(dataObject); @@ -122,30 +104,7 @@ export function newNativeTrackerManager(win) { } } - //Native Render Ad Function - let renderNativeAd = function(nativeTag){ - window.pbNativeData = nativeTag; - const nativeAssetManager = newNativeAssetManager(window); - - if(nativeTag.hasOwnProperty('adId')) { - if(nativeTag.hasOwnProperty('rendererUrl') && !nativeTag.rendererUrl.match(/##.*##/i)){ - const scr = document.createElement('SCRIPT'); - scr.src = nativeTag.rendererUrl, - scr.id = 'pb-native-renderer'; - document.body.appendChild(scr); - } - nativeAssetManager.loadAssets(nativeTag.adId,fireNativeCallback); - fireNativeCallback(); - fireNativeImpTracker(nativeTag.adId); - }else{ - console.warn('Prebid Native Tag object was missing \'adId\'.'); - } - - - } - return { - startTrackers, - renderNativeAd + startTrackers } } diff --git a/src/nativeTrackers.js b/src/nativeTrackers.js index 192c3f49..590ced8d 100644 --- a/src/nativeTrackers.js +++ b/src/nativeTrackers.js @@ -1,8 +1,10 @@ import { newNativeTrackerManager } from './nativeTrackerManager'; +import { newNativeRenderManager } from './nativeRenderManager'; window.pbNativeTag = (window.pbNativeTag || {}); const nativeTrackerManager = newNativeTrackerManager(window); +const nativeRenderManager = newNativeRenderManager(window); window.pbNativeTag.startTrackers = nativeTrackerManager.startTrackers; -window.pbNativeTag.renderNativeAd = nativeTrackerManager.renderNativeAd; +window.pbNativeTag.renderNativeAd = nativeRenderManager.renderNativeAd; diff --git a/test/spec/nativeRenderManager_spec.js b/test/spec/nativeRenderManager_spec.js new file mode 100644 index 00000000..4e0579be --- /dev/null +++ b/test/spec/nativeRenderManager_spec.js @@ -0,0 +1,93 @@ +import { newNativeRenderManager } from 'src/nativeRenderManager'; +import { expect } from 'chai'; +import { mocks } from 'test/helpers/mocks'; +import { merge } from 'lodash'; + +const renderingMocks = { + getWindowObject: function() { + return { + document: {}, + parent: { + postMessage: sinon.spy() + } + } + } +}; + +function trimPort(url) { + return ((/:\d+/).test(url)) ? url.substring(0, url.lastIndexOf(':')) : url; +} + +describe('nativeRenderManager', function () { + describe('load renderNativeAd', function () { + let mockWin; + let consoleWarn; + + let tagData = { + pubUrl: 'http://example.com', + adId: 'ad123', + assetsToReplace: ['image','hb_native_linkurl','body','title'], + }; + + beforeEach(function () { + mockWin = merge(mocks.createFakeWindow(tagData.pubUrl), renderingMocks.getWindowObject()); + consoleWarn = sinon.stub(console, 'warn'); + }); + + afterEach(function () { + consoleWarn.restore(); + }); + + it('should verify the postMessage for impression trackers was executed', function() { + mockWin.document.getElementsByClassName = () => [{ + attributes: { + pbAdId: { + value: 'ad123' + } + }, + addEventListener: (type, listener, capture) => { + }, + }]; + let nativeTracker = new newNativeRenderManager(mockWin); + nativeTracker.renderNativeAd(tagData); + + expect(mockWin.parent.postMessage.callCount).to.equal(1); + let postMessageTargetDomain = mockWin.parent.postMessage.args[0][1]; + let postMessageContents = mockWin.parent.postMessage.args[0][0]; + let rawPostMessage = JSON.parse(postMessageContents); + + expect(rawPostMessage.message).to.exist.and.to.equal("Prebid Native"); + expect(rawPostMessage.adId).to.exist.and.to.equal("ad123"); + expect(rawPostMessage.action).to.not.exist; + expect(trimPort(postMessageTargetDomain)).to.equal(tagData.pubUrl); + }); + + it('should verify the postMessages for the impression and click trackers were executed', function() { + mockWin.document.getElementsByClassName = () => [{ + attributes: { + pbAdId: { + value: 'ad123' + } + }, + addEventListener: ((type, listener, capture) => { + listener({ + }) + }) + }]; + + let nativeTracker = new newNativeRenderManager(mockWin); + nativeTracker.renderNativeAd(tagData); + + expect(mockWin.parent.postMessage.callCount).to.equal(2); + + let postMessageTargetDomain = mockWin.parent.postMessage.args[0][1]; + let postMessageContents = mockWin.parent.postMessage.args[0][0]; + let rawPostMessage = JSON.parse(postMessageContents); + + expect(rawPostMessage.message).to.exist.and.to.equal("Prebid Native"); + expect(rawPostMessage.adId).to.exist.and.to.equal("ad123"); + expect(rawPostMessage.action).to.exist.and.to.equal('click'); + expect(trimPort(postMessageTargetDomain)).to.equal(tagData.pubUrl); + }); + }); +}); diff --git a/test/spec/nativeTrackerManager_spec.js b/test/spec/nativeTrackerManager_spec.js index dc0b44ad..03245537 100644 --- a/test/spec/nativeTrackerManager_spec.js +++ b/test/spec/nativeTrackerManager_spec.js @@ -95,7 +95,7 @@ describe('nativeTrackerManager', function () { expect(trimPort(postMessageTargetDomain)).to.equal(tagData.pubUrl); }); - it('should verify the postMessage for impression trackers was executed', function() { + /*it('should verify the postMessage for impression trackers was executed', function() { mockWin.document.getElementsByClassName = () => [{ attributes: { pbAdId: { @@ -145,7 +145,7 @@ describe('nativeTrackerManager', function () { expect(rawPostMessage.adId).to.exist.and.to.equal("ad123"); expect(rawPostMessage.action).to.exist.and.to.equal('click'); expect(trimPort(postMessageTargetDomain)).to.equal(tagDataAlt.pubUrl); - }); + });*/ it('should verify 2 warning messages (one for impression, one for click) was executed', function() { mockWin.document.getElementsByClassName = () => [{ From 4f11052515bd3c0f0e358eff7cb060bca257a2f8 Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Thu, 23 Jul 2020 16:42:04 -0400 Subject: [PATCH 03/14] Updates to fix lint errors and remove commented code --- dist/load-cookie.html | 16 -------- src/nativeAssetManager.js | 16 ++++---- src/nativeRenderManager.js | 10 ++--- src/nativeTrackerManager.js | 1 - test/spec/nativeTrackerManager_spec.js | 52 -------------------------- 5 files changed, 13 insertions(+), 82 deletions(-) delete mode 100755 dist/load-cookie.html diff --git a/dist/load-cookie.html b/dist/load-cookie.html deleted file mode 100755 index 98bf7a1c..00000000 --- a/dist/load-cookie.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - Document - - - - - \ No newline at end of file diff --git a/src/nativeAssetManager.js b/src/nativeAssetManager.js index 2819d86c..2c6304d8 100644 --- a/src/nativeAssetManager.js +++ b/src/nativeAssetManager.js @@ -168,17 +168,17 @@ export function newNativeAssetManager(win) { function loadAssets(adId, cb) { const placeholders = scanForPlaceholders(adId), flag = (typeof win.pbNativeData !== 'undefined'); - if(flag && win.pbNativeData.hasOwnProperty('assetsToReplace')) { + if (flag && win.pbNativeData.hasOwnProperty('assetsToReplace')) { win.pbNativeData.assetsToReplace.forEach((asset) => { const key = (asset.match(/hb_native_/i)) ? asset : NATIVE_KEYS[asset]; - if(key) {placeholders.push(key);} + if (key) {placeholders.push(key);} }); } if (placeholders.length > 0) { callback = cb; requestAssets(adId, placeholders); - }else if(flag && win.pbNativeData.hasOwnProperty('requestAllAssets') && win.pbNativeData.requestAllAssets) { + }else if (flag && win.pbNativeData.hasOwnProperty('requestAllAssets') && win.pbNativeData.requestAllAssets) { callback = cb; requestAllAssets(adId); } @@ -273,13 +273,13 @@ export function newNativeAssetManager(win) { if (data.message === 'assetResponse') { const body = win.document.body.innerHTML,flag = (typeof win.pbNativeData !== 'undefined'); - if((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (flag && win.pbNativeData.hasOwnProperty('rendererUrl'))) { - if(win.renderAd){ + if ((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (flag && win.pbNativeData.hasOwnProperty('rendererUrl'))) { + if (win.renderAd) { const newHtml = (win.renderAd && win.renderAd(data.assets)) || ''; win.document.body.innerHTML = body + newHtml; callback && callback(); win.removeEventListener('message', replaceAssets); - } else if(document.getElementById('pb-native-renderer')) { + } else if (document.getElementById('pb-native-renderer')) { document.getElementById('pb-native-renderer').addEventListener('load', function() { const newHtml = (win.renderAd && win.renderAd(data.assets)) || ''; win.document.body.innerHTML = body + newHtml; @@ -287,14 +287,14 @@ export function newNativeAssetManager(win) { win.removeEventListener('message', replaceAssets); }); } else { - loadScript(win, ((flag && win.pbNativeData.hasOwnProperty('rendererUrl') && win.pbNativeData.rendererUrl) || data.rendererUrl), function(){ + loadScript(win, ((flag && win.pbNativeData.hasOwnProperty('rendererUrl') && win.pbNativeData.rendererUrl) || data.rendererUrl), function() { const newHtml = (win.renderAd && win.renderAd(data.assets)) || ''; win.document.body.innerHTML = body + newHtml; callback && callback(); win.removeEventListener('message', replaceAssets); }) } - } else if((data.hasOwnProperty('adTemplate') && data.adTemplate)||(flag && win.pbNativeData.hasOwnProperty('adTemplate'))) { + } else if ((data.hasOwnProperty('adTemplate') && data.adTemplate)||(flag && win.pbNativeData.hasOwnProperty('adTemplate'))) { const template = (flag && win.pbNativeData.hasOwnProperty('adTemplate') && win.pbNativeData.adTemplate) || data.adTemplate; const newHtml = replace(template, data); diff --git a/src/nativeRenderManager.js b/src/nativeRenderManager.js index 8c90a853..0e68ee2b 100644 --- a/src/nativeRenderManager.js +++ b/src/nativeRenderManager.js @@ -35,11 +35,11 @@ export function newNativeRenderManager(win) { } } - function fireNativeImpTracker(adId){ + function fireNativeImpTracker(adId) { fireTracker(adId, 'impression'); } - function fireNativeCallback(){ + function fireNativeCallback() { const adElements = findAdElements(AD_ANCHOR_CLASS_NAME); for (let i = 0; i < adElements.length; i++) { adElements[i].addEventListener('click', function(event) { @@ -49,16 +49,16 @@ export function newNativeRenderManager(win) { } // START OF MAIN CODE - let renderNativeAd = function(nativeTag){ + let renderNativeAd = function(nativeTag) { window.pbNativeData = nativeTag; const targetingData = transformAuctionTargetingData(nativeTag); const nativeAssetManager = newNativeAssetManager(window); - if(nativeTag.hasOwnProperty('adId')) { + if (nativeTag.hasOwnProperty('adId')) { let parsedUrl = parseUrl(window.pbNativeData.pubUrl); publisherDomain = parsedUrl.protocol + '://' + parsedUrl.host; - if(nativeTag.hasOwnProperty('rendererUrl') && !nativeTag.rendererUrl.match(/##.*##/i)){ + if (nativeTag.hasOwnProperty('rendererUrl') && !nativeTag.rendererUrl.match(/##.*##/i)) { const scr = document.createElement('SCRIPT'); scr.src = nativeTag.rendererUrl, scr.id = 'pb-native-renderer'; diff --git a/src/nativeTrackerManager.js b/src/nativeTrackerManager.js index 81d97e78..a8bb9dba 100644 --- a/src/nativeTrackerManager.js +++ b/src/nativeTrackerManager.js @@ -10,7 +10,6 @@ const AD_DATA_ADID_ATTRIBUTE = 'pbAdId'; export function newNativeTrackerManager(win) { let publisherDomain; - function findAdElements(className) { let adElements = win.document.getElementsByClassName(className); return adElements || []; diff --git a/test/spec/nativeTrackerManager_spec.js b/test/spec/nativeTrackerManager_spec.js index 03245537..bcb2d6d9 100644 --- a/test/spec/nativeTrackerManager_spec.js +++ b/test/spec/nativeTrackerManager_spec.js @@ -95,58 +95,6 @@ describe('nativeTrackerManager', function () { expect(trimPort(postMessageTargetDomain)).to.equal(tagData.pubUrl); }); - /*it('should verify the postMessage for impression trackers was executed', function() { - mockWin.document.getElementsByClassName = () => [{ - attributes: { - pbAdId: { - value: 'ad123' - } - }, - addEventListener: (type, listener, capture) => { - }, - }]; - let nativeTracker = new newNativeTrackerManager(mockWin); - nativeTracker.renderNativeAd(tagDataAlt); - - expect(mockWin.parent.postMessage.callCount).to.equal(1); - let postMessageTargetDomain = mockWin.parent.postMessage.args[0][1]; - let postMessageContents = mockWin.parent.postMessage.args[0][0]; - let rawPostMessage = JSON.parse(postMessageContents); - - expect(rawPostMessage.message).to.exist.and.to.equal("Prebid Native"); - expect(rawPostMessage.adId).to.exist.and.to.equal("ad123"); - expect(rawPostMessage.action).to.not.exist; - expect(trimPort(postMessageTargetDomain)).to.equal(tagDataAlt.pubUrl); - }); - - it('should verify the postMessages for the impression and click trackers were executed', function() { - mockWin.document.getElementsByClassName = () => [{ - attributes: { - pbAdId: { - value: 'ad123' - } - }, - addEventListener: ((type, listener, capture) => { - listener({ - }) - }) - }]; - - let nativeTracker = new newNativeTrackerManager(mockWin); - nativeTracker.renderNativeAd(tagDataAlt); - - expect(mockWin.parent.postMessage.callCount).to.equal(2); - - let postMessageTargetDomain = mockWin.parent.postMessage.args[0][1]; - let postMessageContents = mockWin.parent.postMessage.args[0][0]; - let rawPostMessage = JSON.parse(postMessageContents); - - expect(rawPostMessage.message).to.exist.and.to.equal("Prebid Native"); - expect(rawPostMessage.adId).to.exist.and.to.equal("ad123"); - expect(rawPostMessage.action).to.exist.and.to.equal('click'); - expect(trimPort(postMessageTargetDomain)).to.equal(tagDataAlt.pubUrl); - });*/ - it('should verify 2 warning messages (one for impression, one for click) was executed', function() { mockWin.document.getElementsByClassName = () => [{ addEventListener: ((type, listener, capture) => { From b8d8f228927d4d8b7a1c64b7be10835f4d830673 Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Fri, 9 Oct 2020 16:44:52 -0400 Subject: [PATCH 04/14] Revert package-lock --- package-lock.json | 200 ++++++++++++++++------------------------------ 1 file changed, 67 insertions(+), 133 deletions(-) diff --git a/package-lock.json b/package-lock.json index d02ab05e..d816842c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid-universal-creative", - "version": "1.9.0-pre", + "version": "1.6.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -4594,29 +4594,25 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "bundled": true, "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": false, - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "bundled": true, "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "bundled": true, "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": false, - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4626,15 +4622,13 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "bundled": true, "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": false, - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4644,43 +4638,37 @@ }, "chownr": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "bundled": true, "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "bundled": true, "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "bundled": true, "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "bundled": true, "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "bundled": true, "dev": true, "optional": true }, "debug": { "version": "4.1.1", - "resolved": false, - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4689,29 +4677,25 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": false, - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "bundled": true, "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "bundled": true, "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bundled": true, "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": false, - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4720,15 +4704,13 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "bundled": true, "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4744,8 +4726,7 @@ }, "glob": { "version": "7.1.3", - "resolved": false, - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4759,15 +4740,13 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "bundled": true, "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": false, - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4776,8 +4755,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": false, - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4786,8 +4764,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4797,22 +4774,19 @@ }, "inherits": { "version": "2.0.3", - "resolved": false, - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "bundled": true, "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": false, - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "bundled": true, "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4821,15 +4795,13 @@ }, "isarray": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "bundled": true, "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": false, - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4838,15 +4810,13 @@ }, "minimist": { "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "bundled": true, "dev": true, "optional": true }, "minipass": { "version": "2.3.5", - "resolved": false, - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4856,8 +4826,7 @@ }, "minizlib": { "version": "1.2.1", - "resolved": false, - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4866,8 +4835,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4876,15 +4844,13 @@ }, "ms": { "version": "2.1.1", - "resolved": false, - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "bundled": true, "dev": true, "optional": true }, "needle": { "version": "2.3.0", - "resolved": false, - "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4895,8 +4861,7 @@ }, "node-pre-gyp": { "version": "0.12.0", - "resolved": false, - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4914,8 +4879,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": false, - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4925,15 +4889,13 @@ }, "npm-bundled": { "version": "1.0.6", - "resolved": false, - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", + "bundled": true, "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "resolved": false, - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4943,8 +4905,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4956,22 +4917,19 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "bundled": true, "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": false, - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "bundled": true, "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -4980,22 +4938,19 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "bundled": true, "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "bundled": true, "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": false, - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5005,22 +4960,19 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "bundled": true, "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "bundled": true, "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "resolved": false, - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5032,8 +4984,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "bundled": true, "dev": true, "optional": true } @@ -5041,8 +4992,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5057,8 +5007,7 @@ }, "rimraf": { "version": "2.6.3", - "resolved": false, - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5067,50 +5016,43 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": false, - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "bundled": true, "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": false, - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "bundled": true, "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": false, - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "bundled": true, "dev": true, "optional": true }, "semver": { "version": "5.7.0", - "resolved": false, - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "bundled": true, "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": false, - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "bundled": true, "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5121,8 +5063,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5131,8 +5072,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": false, - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5141,15 +5081,13 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "bundled": true, "dev": true, "optional": true }, "tar": { "version": "4.4.8", - "resolved": false, - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5164,15 +5102,13 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true, "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": false, - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "bundled": true, "dev": true, "optional": true, "requires": { @@ -5181,15 +5117,13 @@ }, "wrappy": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "bundled": true, "dev": true, "optional": true }, "yallist": { "version": "3.0.3", - "resolved": false, - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "bundled": true, "dev": true, "optional": true } From 6cacfc5786a94899f35349185121905ca5f5f7e4 Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Fri, 9 Oct 2020 16:46:33 -0400 Subject: [PATCH 05/14] Remove DS_Store --- .DS_Store | Bin 10244 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 03dd42d786cf4337861c940bf810b391df4ef6ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHMJ!~9B6n<-;&wI9`*aYE{l@L;djAcWV#6n2t^I6EkfrvvOlpy`+<}ikx!x;HXeXO)(r9j&_gTVT;NRrIq32$Z&GhlN~ifam3RR=LvUmiqhJnWxz6! zW}t*yF0E3Hs@S#pdo74+Xyec673}B#5gX2k3h=K}lV|#v@B4htGkz`Nn@2|k2kVu3 z)M|^2lwZlt+ltC%mDl}k{@O2pz5e6oB+tfw^lTsMPZs?}4iz1sqMliYvz(|S_A}5g ze)=o?;x--gAJ3H@D9l>>7-?3!fp6&^Qq$}RA01MkY6+CL6DSkj23DH+I-O5PeCu4y zaw1PF8snbqWuT`uMn4y$Z-V8JA}GgC)bMAbhCE_II-=HSJxNm+>+!Cp$1_lF2U!Qy zg&I3JuF?%0BMQx@5bIKpoIzwC?>(S~=_%g)1kc)_+g50PsTWE8!xYTmoJ{Ic*h$TURv=kZLFW16x`+K z*I(V)Z+-Of@h2y@?xJpNjv74ath|noU*JsR!ca_p>!R7JtL51jzQ4VBMSPQ5ysngN z4?`vSAp_Ckk1Cxoh{6NhWyCpZ;2m{SUnlEce@C&OfuEjXzqn0D|M{1H-}r1-px4^R zD$i;+kduehG!Iqxp`kW?AhhI5{UsE|3fIw|qnqe+J5YEP{&iL>;#bA>O`&6hqh>&-k=I?C%mC|!+Sw|eGO#a!*e3=%D8>%nsKatBW?+`Re_NaAHe@b zL`C9y!k6ZNb0fn-BEzIOuw=v)=q=Q?NoBeM%j_h+RKduH8Y54Mh+Po{Mo{Th+<8-Q zQ~^g>IhZFsM*;5ztf0m|&gv5wdPIb&Lgy>I|BSr49t+>aeQ&1cSed7Lni>@&+%&3D zEA!)?RJ#YYY$_zaqAdiy464>dm@*5;I;*A1W*>v6FOuy==f6p zCemphuTwrc=Kjp}(Qk+hzcKpL{ERx}bR{S1NcB)co4;$?jQvd9;XZK3Z93kc-;42T z?PHu-?IyklNDbXF&%h_XLjHmiUp$YDj*c`V!o+;^Fgve~e(6q(J|mw#N}TR#R`df` zw1Cl`M}^4fJ2C1f6vRE5Ue{T~`55&_{h8kLrlYwR)1Ì!pv1}pn$Icu34W$(!IIs)f7t8Uu;N|%9 z>Yi8xQs+fwhti60#EEcNxtjmK{}~|HHr=fGz5c5-tKIx9>Twx%{-0WDv-5xIn)9W{ HZT|l+M$DcO From a4d5f58050db2a3ad8bfe9c604dcca0b3c20d088 Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Tue, 20 Oct 2020 12:03:07 -0400 Subject: [PATCH 06/14] Update to separate new native functionality into new native-render.js file to avoid loading unused code lib --- gulpfile.js | 29 +++++++++++++++++++++++++---- src/nativeRender.js | 7 +++++++ src/nativeTrackers.js | 3 --- 3 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 src/nativeRender.js diff --git a/gulpfile.js b/gulpfile.js index 7f865591..7273b491 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -45,6 +45,15 @@ function buildNativeDev() { .pipe(gulp.dest('build')); } +function buildNativeRenderDev() { + var cloned = _.cloneDeep(webpackConfig); + cloned.output.filename = 'native-render.js'; + + return gulp.src(['src/nativeRender.js']) + .pipe(webpackStream(cloned)) + .pipe(gulp.dest('build')); +} + function buildCookieSync() { let cloned = _.cloneDeep(webpackConfig); delete cloned.devtool; @@ -103,6 +112,18 @@ function buildNative() { .pipe(gulp.dest('dist')); } +function buildNativeRender() { + var cloned = _.cloneDeep(webpackConfig); + delete cloned.devtool; + cloned.output.filename = 'native-render.js'; + + return gulp.src(['src/nativeRender.js']) + .pipe(webpackStream(cloned)) + .pipe(uglify()) + .pipe(header('/* v<%= creative.version %>\n' + dateString + ' */\n', { creative: creative })) + .pipe(gulp.dest('dist')); +} + function buildUid() { var cloned = _.cloneDeep(webpackConfig); delete cloned.devtool; @@ -160,7 +181,7 @@ function setupE2E(done) { gulp.task('test', gulp.series(clean, test)); -gulp.task('e2e-test', gulp.series(clean, setupE2E, gulp.parallel(buildDev, buildCookieSync, buildNativeDev, buildUidDev, watch), test)); +gulp.task('e2e-test', gulp.series(clean, setupE2E, gulp.parallel(buildDev, buildCookieSync, buildNativeDev, buildNativeRenderDev, buildUidDev, watch), test)); function watch(done) { const mainWatcher = gulp.watch([ @@ -175,7 +196,7 @@ function watch(done) { root: './' }); - mainWatcher.on('all', gulp.series(clean, gulp.parallel(buildDev, buildNativeDev, buildCookieSync, buildUidDev), test)); + mainWatcher.on('all', gulp.series(clean, gulp.parallel(buildDev, buildNativeDev, buildNativeRenderDev, buildCookieSync, buildUidDev), test)); done(); } @@ -183,9 +204,9 @@ function openWebPage() { return opens(`${(argv.https) ? 'https' : 'http'}://localhost:${port}`); } -gulp.task('serve', gulp.series(clean, gulp.parallel(buildDev, buildNativeDev, buildCookieSync, buildUidDev, watch, test), openWebPage)); +gulp.task('serve', gulp.series(clean, gulp.parallel(buildDev, buildNativeDev, buildNativeRenderDev, buildCookieSync, buildUidDev, watch, test), openWebPage)); -gulp.task('build', gulp.parallel(buildProd, buildCookieSync, buildNative, buildUid)); +gulp.task('build', gulp.parallel(buildProd, buildCookieSync, buildNative, buildNativeRender, buildUid)); gulp.task('test-coverage', (done) => { new KarmaServer(karmaConfMaker(true, false, false), newKarmaCallback(done)).start(); diff --git a/src/nativeRender.js b/src/nativeRender.js new file mode 100644 index 00000000..8636abed --- /dev/null +++ b/src/nativeRender.js @@ -0,0 +1,7 @@ +import { newNativeRenderManager } from './nativeRenderManager'; + +window.pbNativeTag = (window.pbNativeTag || {}); +const nativeRenderManager = newNativeRenderManager(window); + +window.pbNativeTag.renderNativeAd = nativeRenderManager.renderNativeAd; + diff --git a/src/nativeTrackers.js b/src/nativeTrackers.js index 590ced8d..d9e20fd7 100644 --- a/src/nativeTrackers.js +++ b/src/nativeTrackers.js @@ -1,10 +1,7 @@ import { newNativeTrackerManager } from './nativeTrackerManager'; -import { newNativeRenderManager } from './nativeRenderManager'; window.pbNativeTag = (window.pbNativeTag || {}); const nativeTrackerManager = newNativeTrackerManager(window); -const nativeRenderManager = newNativeRenderManager(window); window.pbNativeTag.startTrackers = nativeTrackerManager.startTrackers; -window.pbNativeTag.renderNativeAd = nativeRenderManager.renderNativeAd; From f436d1e714e4f05398f51704434ff84d48409826 Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Wed, 21 Oct 2020 15:39:05 -0400 Subject: [PATCH 07/14] Added line to message event listener to validate that if new nativeRenderer exists then adId in message must match adId in creative window, before replacing assets --- src/nativeAssetManager.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nativeAssetManager.js b/src/nativeAssetManager.js index 2c6304d8..c5b53950 100644 --- a/src/nativeAssetManager.js +++ b/src/nativeAssetManager.js @@ -273,6 +273,8 @@ export function newNativeAssetManager(win) { if (data.message === 'assetResponse') { const body = win.document.body.innerHTML,flag = (typeof win.pbNativeData !== 'undefined'); + if (flag && data.adId != win.pbNativeData.adId) return; + if ((data.hasOwnProperty('rendererUrl') && data.rendererUrl) || (flag && win.pbNativeData.hasOwnProperty('rendererUrl'))) { if (win.renderAd) { const newHtml = (win.renderAd && win.renderAd(data.assets)) || ''; From 319ac691ac19b8a011e860de8e8fc0d34c9cdab4 Mon Sep 17 00:00:00 2001 From: Michael Moschovas Date: Wed, 21 Oct 2020 16:05:47 -0400 Subject: [PATCH 08/14] Added test for mismatch adId in replaceAsset response --- test/spec/nativeAssetManager_spec.js | 98 ++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/test/spec/nativeAssetManager_spec.js b/test/spec/nativeAssetManager_spec.js index 081ebe54..d6665b17 100644 --- a/test/spec/nativeAssetManager_spec.js +++ b/test/spec/nativeAssetManager_spec.js @@ -5,6 +5,7 @@ import { mocks } from 'test/helpers/mocks'; import * as utils from 'src/utils'; const AD_ID = 'abc123'; +const AD_ID2 = 'def456'; const NATIVE_KEYS = { title: 'hb_native_title', body: 'hb_native_body', @@ -56,6 +57,16 @@ function createAllResponder(assets,url,template) { }; } +// creates mock postmessage response from prebid's native.js:getAssetMessage using alternative id +function createAltAllResponder(assets,url,template) { + return function(type, listener) { + if (type !== 'message') { return; } + + const data = { message: 'assetResponse', adId: AD_ID2, assets, adTemplate:template, rendererUrl:url }; + listener({ data: JSON.stringify(data) }); + }; +} + // creates mock html markup responsse from renderUrl function generateRenderer(assets) { let newhtml = '
\r\n
<\/div>\r\n
\r\n

\r\n ##hb_native_title##<\/a>\r\n <\/h1>\r\n

##hb_native_body##<\/p>\r\n \t

\r\n \t\"icon\"\r\n \t\r\n \t<\/div>\r\n\t<\/div>\r\n<\/div>'; @@ -191,6 +202,93 @@ describe('nativeTrackerManager', () => { expect(win.document.body.innerHTML).to.include(`

Body content

`); }); + it('adId does not match, so assets are not replaced', () => { + const html = ``; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : 'OTHERID123', + rendererUrl : 'https://www.renderer.com/render.js', + requestAllAssets : true + }; + + win.document.body.innerHTML = html; + win.renderAd = generateRenderer; + + win.addEventListener = createAllResponder([ + { key: 'body', value: 'Body content' }, + { key: 'title', value: 'new value' }, + { key: 'clickUrl', value: 'http://www.example.com' }, + { key: 'image', value: 'http://www.image.com/picture.jpg' }, + ],null,null); + + const nativeAssetManager = newNativeAssetManager(win); + nativeAssetManager.loadAssets(AD_ID); + + expect(win.document.body.innerHTML).to.equal(``); + }); + + it('adId does not match on first response, so assets are not replaced until match on second response', () => { + const html = ``; + win.pbNativeData = { + pubUrl : 'https://www.url.com', + adId : 'def456', + rendererUrl : 'https://www.renderer.com/render.js', + requestAllAssets : true + }; + + win.document.body.innerHTML = html; + win.renderAd = generateRenderer; + + win.addEventListener = createAllResponder([ + { key: 'body', value: 'Body No Replace' }, + { key: 'title', value: 'new value no replace' }, + { key: 'clickUrl', value: 'http://www.example.com/noreplace' }, + { key: 'image', value: 'http://www.image.com/picture.jpg?noreplace=true' }, + ],null,null); + + const nativeAssetManager = newNativeAssetManager(win); + nativeAssetManager.loadAssets(AD_ID2); + + expect(win.document.body.innerHTML).to.equal(``); + + win.addEventListener = createAltAllResponder([ + { key: 'body', value: 'Body content' }, + { key: 'title', value: 'new value' }, + { key: 'clickUrl', value: 'http://www.example.com' }, + { key: 'image', value: 'http://www.image.com/picture.jpg' }, + ],null,null); + + nativeAssetManager.loadAssets(AD_ID2); + + expect(win.document.body.innerHTML).to.include(`
new value`); + expect(win.document.body.innerHTML).to.include(`icon`); + expect(win.document.body.innerHTML).to.include(`

Body content

`); + }); + it('no placeholders found but requests all assets flag set - rendererUrl', () => { const html = `